2012-04-07 145 views
0

我想从互联网获取数据,解析它,然后将数据显示给用户。这个动作通常需要3秒钟左右,我想一个微调的ProgressDialog显示一条消息,说我正在加载数据。问题在于ProgressDialog仅在加载完成时才显示。这是我的代码ProgressDialog不会立即显示

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button load_routes = (Button)findViewById(R.id.load_routes); 

    load_routes.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      task_complete = false; 
      progressBar = new ProgressDialog(v.getContext()); 
      progressBar.setCancelable(false); 
      progressBar.setMessage("Fetching routes data ..."); 
      progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
      progressBar.show(); 

      if(haveNetworkConnection()) 
      { 
       loading_routes_data(v); 
      } 
      else 
      { 
       progressBar.dismiss(); 
      } 
     } 
    }); 
} 

这是我的函数,得到的onclick称为

private void loading_routes_data(View v) 
{ 
    try 
    { 
     new Thread(new Runnable() 
     { 
      public void run() 
      { 
       while(!task_complete) 
       { 
        refresh_routes(); 
        try 
        { 
         Thread.sleep(1000); 
        } 
        catch(InterruptedException e) 
        { 
         e.printStackTrace(); 
        } 
       } 
       runOnUiThread(new Runnable() 
       { 
        public void run() 
        { 
         progressBar.dismiss(); 
        } 
       }); 
      } 
     }).start(); 
    } 
    catch(Exception e) 
    { 
    } 

    while(!task_complete) 
    { 
    } 
} 

refresh_routes()函数获取数据,对其进行解析,然后设置task_completetrue,我不是是否甚至不确定或者我不应该把它留在while循环中。

所以这是我的大问题。我想在按钮点击时立即显示ProgressDialog,然后我想拨打refresh_routes(),并且一旦refresh_routes()完成,我想摆脱进度对话框。但我不确定如何去做这件事。

如果有人能告诉我如何解决问题的一些文章作为例子或类似的东西,我会非常感激。预先感谢您:)

回答

2

通过在方法的结尾调用while(!task_complete)来锁定UI线程。你真的应该使用一个AsyncTask这样的操作。这是你的AsyncTask应该是什么样子:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { 

    private ProgressDialog progressDialog; 
    private Context context; 

    public MyAsyncTask(Context context) { 

     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 
     progressDialog = ProgressDialog.show(context, null, "Fetching routes data ..."); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     while (!task_complete) { 
      refresh_routes(); 
      try { 
       Thread.sleep(1000); 
      } 
      catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     super.onPostExecute(result); 
     progressDialog.dismiss(); 
    } 
} 

要执行此,你可以这样做:

new MyAsyncTask(this).execute(); 

我不知道你的refresh_routes()方法是如何工作的,但你可能会考虑将它的功能里面方法doInBackground()

+0

太棒了,它的工作!网上的所有教程都表示使用线程,但这太神奇了。你也会碰巧知道是否有任何方法可以调用一个函数来接受视图作为异步的参数? – Quillion 2012-04-07 01:12:40

+0

如果您需要在后台进程运行时显示进度,请覆盖'onProgressUpdate(...)'方法。然后触发一个动作,你可以在'doInBackground()'方法内调用'publishProgress(...)'。它会自动在UI线程上运行。请阅读有关'AsyncTask'的文档以了解所有内容如何组合在一起。 – 2012-04-09 04:52:16

1

使用AsyncTask来做到这一点。它为您提供了在Activity中执行多线程的强大功能。