如何使用AsyncTask和线程?

时间:2012-04-28 11:22:20

标签: android

目标:
使用Google App Engine服务器和Android客户端,我正试图在Android客户端用户覆盖上放置谷歌地图。每隔30秒我就会轮询服务器并获取包含用户的Vector并将其添加到地图中。

当前状态:
我在一个新线程中使用了所有这些,所以在运行应用程序之后我得到了:
奇怪的行为(延迟叠加,多个叠加),然后用ConcurrentModificationException粉碎 读了一下后,我发现我需要使用 AsyncTask

如果我错了,请纠正我,但我明白在onCreate的Activity中所做的一切都在UIhread中“运行”所以我需要在doInBackground和所有UI中放置“Logic”(所有网络处理)处理就像在onPostExecute中将叠加层放在地图上一样。

我的问题是:
1)在我正在做的当前状态:

new Thread()
{
    @Override
    public void run() 
    {           
        super.run();
        while(true)
        {
            SystemClock.sleep(30000);   
            Vector responseFromServer = getUsersVectorFromServer();             
            putNewOnlineUserOnTheMap();
        }           
    }
}.start();

将此转换为AsyncTask的正确方法是什么?
我是否仍然使用doInBackground中的新线程轮询服务器,或者有正确的方法来执行此操作?

2)是否有一个特定的列表,其中包含要放入onPostExecute或任何概念列表的UI? 在我的情况下,我猜需要将putNewOnlineUserOnTheMap()放在onPostExecute中。

感谢。

3 个答案:

答案 0 :(得分:2)

类似于以下内容:

class UpdateTask extends AsyncTask<Void, Vector, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        // this is running in a background thread.
        while (!isCancelled()) {
            SystemClock.sleep(30000);   
            Vector responseFromServer = getUsersVectorFromServer();
            // send the result back to the UI thread
            // onProgressUpdate will be called then
            publishProgress(responseFromServer);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Vector... values) {
        // this is executed on the UI thread where we can safely touch UI stuff
        putNewOnlineUserOnTheMap(values[0]);
    }

}

由于任务完成,您无法使用任务的结果。但是您可以使用进度发布机制来获得定期结果。如果您使用它并在UI线程上进行修改,则不应该获得ConcurrentModificationException,因为您可以在可以安全地修改UI的一个线程上进行修改。

有一点需要注意:在后台线程中创建Vector的新实例,然后使用它来更新UI。但是之后不要在backgroundthread中触摸同一个对象。这样你就不需要任何同步,因为在后台线程发送它之后它只是触及它的UI线程。 (您可以使用简单的ArrayList代替Vector

答案 1 :(得分:1)

AsyncTask使用泛型和变量。传递给asyntask的参数是。 TypeOfVariableArgumentsParameters传递给doInBackground(),ProgressParam用于进度信息,ResultParam必须从doInBackground()返回,并作为参数传递给onPostExecute()。

例如: - protected class ParsingTask扩展了AsyncTask&gt; {

     private ProgressDialog loadingDialog = new ProgressDialog(JsonParserActivity.this);



     protected void onPreExecute() {
         loadingDialog.setMessage("loading app store..");
         loadingDialog.show();
     }

    @Override
    protected ArrayList<Items> doInBackground( Context... params )  {

        // do ur process here.
        return result;
     }      

        if (!this.isCancelled()) {
        }

        return result;
    }

    @Override
    protected void onProgressUpdate(String... s)   {
        super.onProgressUpdate(s);
        Toast.makeText(getApplicationContext(), s[0], Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onPostExecute( ArrayList<Items> response )  {
    //if u r dealing with list view and adapters set the adapter here at the onPostExecute()
            loadingDialog.dismiss();

    }

    @Override
    protected void onCancelled() {
        super.onCancelled();

        Toast.makeText(getApplicationContext(), "The operation was cancelled", 1).show();
    }

}

答案 2 :(得分:0)

您可以使用如下的AsyncTask。希望这会对你有帮助..

Class YourClass{
    void YourClass(){
       NetworkTask nT = new NetworkTasK();
       nT.execute();
    }
}
protected class NetworkTask extends AsyncTask<Void, String, Boolean>
{
    @Override
    protected Boolean doInBackground(Void... params) 
    {
        try 
        {
            String response;
            while(keepreceiving)
            {
                response = in.readLine();//Prog Counter stops here until getting i/p.

                if(response != null)
                    yourFunctionForResponse(response);
            }
        }

        catch (Exception ex) 
        {

        }
        return null;        
    }
     private void yourFunctionForResponse(String response){
     //things to do....
     }
}

您也可以尝试runOnUiThread(Runnable action)来实现您的工作。