2013-11-21 47 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也很好。我只是没有使用它。 –