我有一个有很多偏好的应用程序。因此,当用户第一次加载首选项时,需要很长时间。因此在加载prefs时UI会冻结。
这就是为什么我想添加一个对话框,告诉用户prefs正在加载。
问题是,加载首选项只允许在UI线程上,因为当我尝试在异步任务中加载我的首选项时,我得到了这个:
错误/ AndroidRuntime(4830):引起: android.view.ViewRoot $ CalledFromWrongThreadException:只有 创建视图层次结构的原始线程可以触及其视图。
因此,当我将runOnUiThread()添加到Async Task时,在AsyncTask中执行它的全部目的都会被破坏:
public class ApplicationPreferences extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new ProgressTask(ApplicationPreferences.this).execute();
}
private class ProgressTask extends AsyncTask<Void, Void, Void> {
private Context context;
private ProgressDialog dialog;
public ProgressTask(ListActivity activity) {
context = activity;
dialog = new ProgressDialog(context);
}
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
runOnUiThread(new Runnable() {
@Override
public void run() {
initPreferences();
}
});
return null;
}
@Override
protected void onPostExecute(Void result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
/*
* THIS TAKES LONG THE FIRST TIME
*/
private void initPreferences() {
addPreferencesFromResource(R.xml.preferences);
// preferences
ListPreference pref1 = (ListPreference) findPreference(getString(R.string.pref1));
// ........ etc
}
public static void start(Context context) {
context.startActivity(new Intent(context, ApplicationPreferences.class));
} }
我怎样才能更好地做到这一点?
答案 0 :(得分:0)
所以当我将runOnUiThread()添加到异步任务的整个目的时 在AsyncTask中执行它会被破坏。
我不太清楚我理解这一点,但是如果你想向用户显示进度对话框,那么用户是否会等待任务完成?
另一方面,如果你想在真实的后台任务中加载首选项,请使用普通的java线程 - 非UI线程确实无法创建AsyncTasks。
修改:在您添加的评论之后,这可能会对您有所帮助(在ApplicationPreferences#onCreate中更改部分代码):
ProgressTask pTask = new ProgressTask(ApplicationPreferences.this);
pTask.execute();
// Wait for the async task to finish the specified amount of time.
pTask.get(10, TimeUnit.SECONDS); // Choose appropriate timeframe
这样主线程就会停止,希望能处理奇怪的行为。
再一次:如果我还没有解决你的问题,请随时发表评论。
答案 1 :(得分:0)
我提出了我能想到的最佳解决方案:
如果您有一个非常大的偏好文件,则必须致电
PreferenceManager.setDefaultValues(context, R.xml.mypreferencefile, false);
在UI线程上的某个时刻。
我是在应用初始化阶段结束时这样做的。通过这种方式,用户对应用程序的一些短暂冻结最不安。
此命令首次使用默认值初始化文件。之后,该文件可用,并且可以非常快速地访问。