gpt4 book ai didi

android - AsyncTask 的 doInBackground 方法阻塞 UI 线程

转载 作者:搜寻专家 更新时间:2023-11-01 08:13:57 24 4
gpt4 key购买 nike

我正在 AsyncTask 中加载一些 JSON 数据,因为我想在 UI 中显示下载进度。下载工作正常并且 publishProgress 方法被定期调用(每 100 个 JSON 对象),但 onProgressUpdate 和 onPostExecute 不会真正执行,直到所有后台操作完成(即所有需要 doInBackground 结果的计算)。

日志大概是这样的:

AsyncTaskCaller.downloadWithAsyncTask: executing AsyncTask

MyAsyncTask.onPreExecute: AsyncTask started

MyAsyncTask.doInBackground: Download 0%
MyAsyncTask.doInBackground: Download 10%
...
MyAsyncTask.doInBackground: Download 90%
MyAsyncTask.doInBackground: Download 100%

AsyncTaskCaller.processResult: Results processed

// all background calculations finished

MyAsyncTask.onProgressUpdate: Download 0%
MyAsyncTask.onProgressUpdate: Download 10%
...
MyAsyncTask.onProgressUpdate: Download 90%
MyAsyncTask.onProgressUpdate: Download 100%

MyAsyncTask.onPostExecute: AsyncTask ended

MyActivity.updateUiAfterDownload

这是我的代码调用数据的方式:

我的 Activity :

final Runnable mSynchroniseContacts = new Runnable() {
public void run() {
/** get oAuth tokens for synchronisation */
MyApp app = (MyApp) getApplication();
OpenAuthTokens myTokens = app.getAccessTokens();

// mockup code to load contacts
MyContact[] contacts = AsyncTaskCaller.loadContacts(myTokens, MyActivity.this);
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.synchronisation_activity);

statusText = (TextView) findViewById(R.id.synchronisation_status_text);

mSynchroniseContacts.run();
}

AsyncTaskCaller:

private static JSONArray records = null;

public static MyContact[] loadContacts(OpenAuthTokens myTokens, Context context) {
MyAsyncTask contactDownloader = new MyAsyncTask(context, myTokens) {
@Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);

records = result; // assigning result to static class variable, to avoid calling contactDownloader.get(), which apparently blocks the UI thread according to http://stackoverflow.com/questions/5583137/asynctask-block-ui-threat-and-show-progressbar-with-delay
}
};

contactDownloader.execute(url);

// wait until contacts are downloaded
while(!SforceContactDownloadTask2.isFinished()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Log.e(TAG, e.getCause() + " - " + e.getMessage());
e.printStackTrace();
}
}

// some code to convert JSONArray records into MyContact[] myContacts

return myContacts;
}

MyAsyncTask(没有明确粘贴上面记录的代码):

@Override
protected void onPreExecute() {
finished = false;
}

@Override
protected void onPreExecute() {
finished = false;
}

@Override
protected JSONArray doInBackground(String... url) {

StringBuffer dataString = new StringBuffer();

try {

boolean isOnline = ConnectivtiyChecker.isInternetAvailable(context);

if (isOnline) {

/** send as http get request */
URL urlObject = new URL(url[0]);
HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
conn.addRequestProperty("Authorization", "OAuth " + myTokens.get_access_token());

/** prepare response reader */
JSONArray records = null;
byte data[] = new byte[MAX_BUFFER_SIZE];
int currentByteReadCount = 0;
InputStream stream = null;
BufferedInputStream input = null;

try {
/** get response input stream */
stream = conn.getInputStream();
input = new BufferedInputStream(stream);

/** read response from input stream */
while ((currentByteReadCount = input.read(data)) != -1) {
String readData = new String(data, 0, currentByteReadCount);
dataString.append(readData);

//code to figure progress out

// publishing the progress (every 5%)...
if (progress % (total / 20) == 0 ) {
publishProgress((int)(progress * 100 / total));
}
}
} catch (Exception e) {
Log.e(TAG, e.getCause() + " - " + e.getMessage());
e.printStackTrace();
} finally {
// close streams
if (input != null) {
input.close();
}
if (stream != null) {
stream.close();
}
}

/** transform response into JSONArray */
String result = dataString.toString();
JSONObject object = (JSONObject) new JSONTokener(result).nextValue();
records = object.getJSONArray("records");

return records;
} else {
return null;
}
} catch (Exception e) {
Log.e(TAG, e.getCause() + " - " + e.getMessage());
e.printStackTrace();
return null;
}
}

@Override
protected void onProgressUpdate(Integer... changed) {
Log.d(TAG, "Download " + changed[0] + "%");
}

@Override
protected void onPostExecute(JSONArray result) {
finished = true;
}

public static boolean isFinished() {
return finished;
}

有什么想法可以解除 UI 的阻塞吗?

最佳答案

您似乎在主应用程序线程上调用 Thread.sleep()。不要这样做。请将您的应用程序编写为适当的异步。

关于android - AsyncTask 的 doInBackground 方法阻塞 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6755379/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com