2013-11-21 43 views
0

我有一個主要的Activity,一個額外的類爲我的片段,並在這個片段是一個AsyncTask,從各種Android庫(Wifi SSID,BSSID等)收集數據, 。當我啓動我的應用程序時,應用程序顯示一個空白屏幕,沒有任何UI。然後在大約2秒後,整個數據被顯示出來。我實際上想在後臺顯示我的TextViews爲「未連接到WiFi網絡」,同時顯示一個ProgressDialog,直到顯示數據。我已經得到了ProgressDialog在我的MainActivity,並要求它在我的AsyncTask onProgressUpdate等待,直到用戶真正看到屏幕上的東西

MainActivity.progressDialog = ProgressDialog.show(MainActivity.c, 
               "ProgressDialog Title", 
               "ProgressDialog Body"); 

我更新我在doInBackground梅索德TextViews(通過片段之外的另一個梅索德)

((Activity) getActivity()).runOnUiThread(new Runnable() { 

Blank Activity

+0

你告訴你在做什麼,但沒有問任何問題。你有什麼問題? – cYrixmorten

+0

我的問題是活動是空白約2秒(而AsyncTask正在執行),然後我可以看到我的TextViews等等,雖然AsyncTask正在執行onViewCreated方法 – moritzg

+0

textviews是用XML聲明的,對不對?所以你不能通過XML設置默認字符串,然後當你準備好數據時,只需使用每個textview的'.setText()'方法? –

回答

2

會太大的評論,所以我只是把它放在這裏。

聽起來就像你正在以不正確的方式使用fragment和AsyncTask。你不應該在doInBackground中做任何與UI有關的事情。

下面是你可以做的一個例子。

我假設以下情形:

  • 你有一個主要活動
  • 您有一個包含片段TextViews
  • 你希望加載使用的AsyncTask的一些數據與progressDialog
  • 後填充TextViews

該方法將是:

  1. 在活動的onCreate中添加片段(如果片段未在佈局中定義,則會自動添加片段)。
  2. 在您的片段像這樣創建的AsyncTask:

    private class LoadData extends AsyncTask<Void, Void, List<String>> { 
    ProgressDialog progressDialog; 
    //declare other objects as per your need 
    @Override 
    protected void onPreExecute() 
    { 
        // getActivity() is available in fragments and returns the activity to which it is attached 
        progressDialog= new ProgressDialog(getActivity()); 
    
        progressDialog.setTitle("ProgressDialog Title"); 
        progressDialog.setMessage("ProgressDialog Body"); 
        progressDialog.setIndeterminate(true) 
        progressDialog.setCancelable(false) 
        progressDialog.show(); 
    
        //do initialization of required objects objects here     
    };  
    
    @Override 
    protected Void doInBackground(Void... params) 
    { 
        List<String> results = new ArrayList<String>(); 
        //do loading operation here 
        //add each of the texts you want to show in results 
        return results; 
    }  
    
    // onPostExecute runs on UI thread 
    @Override 
    protected void onPostExecute(List<String> results) 
    { 
        progressDialog.dismiss(); 
        // iterate results and add the text to your TextViews 
        super.onPostExecute(result); 
    }; 
    } 
    
  3. 啓動的AsyncTask在片段的onCreate:

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        new LoadData().execute(); 
        super.onCreate(savedInstanceState); 
    } 
    

這樣你可以避免調用直接返回到您的活動,這在你的情況下確實不是必須的(除非我誤解)。

否則請發佈所有相關的代碼和佈局。

+0

這不起作用,屏幕保持空白,我根本看不到ProgressDialog! – moritzg

+0

@ igger不正確。可以只是一個簡單的不確定的微調 – cYrixmorten

+0

我想用一個微調器... – moritzg

1

這條線:

我更新我的TextViews在doInBackground我thode

指向您的問題。您需要使用AsyncTask方法onProgressUpdate()發佈到UI線程。您不直接撥打onProgressUpdate(),而是撥打publishProgress()

有趣的是,我昨天在這裏回答了類似的問題:android AsyncTask in foreach

,它包括一個例子。

1

以下是您需要做的事情。 (1)從您運行收集數據的代碼的位置,應首先顯示進度對話框。像這樣:

busy = new ProgressDialog (this); 
busy.setMessage (getString (R.string.busy)); 
busy.setIndeterminate (true); 
busy.setCancelable (false); 
busy.show(); 

(2)然後你開始你的數據收集。這必須在單獨的線程(或Runnable)中完成。做這樣的事情:

Thread thread = new Thread() 
{ 
    @Override 
    public void run() 
    { 
    try 
    { 
     ... gather data ... 

     Message msg = handler.obtainMessage(); 
     msg.what = LOADING_COMPLETE; 
     msg.obj = null; 
     handler.sendMessage (msg); 
    } 
    catch (Exception e) 
    { 
     Message msg = handler.obtainMessage(); 
     msg.what = LOADING_FAILED; 
     msg.obj = e.getMessage(); // maybe pass this along to show to the user 
     handler.sendMessage (msg); 
    } 

    // get rid of the progress dialog 
    busy.dismiss(); 
    busy = null; 
    } 
} 

(3)處理程序添加到活動時接收通知的數據收集完成:

Handler handler = new Handler() 
{ 
    @Override 
    public void handleMessage (Message msg) 
    { 
    if (msg.what == LOADING_COMPLETE) 
     loadingComplete(); 
    else if (msg.what == LOADING_FAILED) 
     loadingFailed ((String)msg.obj); 
    } 
}; 

(4)執行處理程序:

private void loadingComplete() 
{ 
    ... 
} 

private void loadingFailed (String errorMessage) 
{ 
    ... 
} 

這就是要領。

+0

爲什麼使用線程而不是AsyncTask? (只是爲了理解)我認爲一個AsyncTask更好,因爲你不必實現一個Handler ... – moritzg

+1

我也認爲這是一個過度複雜的AsyncTask實現的方式。 – cYrixmorten

+0

AsyncTask也很好。我只是沒有使用它。 –