2

我有一個應用程序,它有很多偏好。所以當用戶首次加載首選項時,需要相當長的一段時間。因此,在加載首選項時UI會凍結。Android將AsyncTask添加到PreferenceActivity以首次加載許多首選項

這就是爲什麼我要添加一個對話框,告訴用戶加載了前導。

的問題是,在加載喜好只允許在UI線程上,因爲當我試圖加載在異步任務我的喜好,我得到這個:

ERROR/AndroidRuntime(4830):造成: android.view.ViewRoot $ CalledFromWrongThreadException:只有創建視圖層次結構的 原始線程可以觸及其視圖。

所以,當我在的AsyncTask添加runOnUiThread()的異步任務做它的全部目的被破壞:

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

我想出了我能想到的最好的解決辦法:如果你有一個非常大的首選項文件

你必須調用

PreferenceManager.setDefaultValues(context, R.xml.mypreferencefile, false); 

在UI線程上的一些點。

我在應用的初始化階段結束時執行此操作。用這種方式,用戶對應用程序的一些簡短的凍結概念就不會感到困惑。

該命令首次使用默認值初始化文件。之後,該文件可用,並可以很快訪問。

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 

這樣,主線程將停止,並希望怪異的行爲將被處理。
再一次:如果我還沒有解決您的問題,請隨時發表評論。

+0

不,它預計等待。但到目前爲止,只有在整個任務完成之前,對話纔會出現。因此,它的菜單 - >設置,然後凍結,然後對話,然後很快顯示前綴 – IHeartAndroid