2

目标:
使用 Google App Engine 服务器和 Android 客户端,我试图将 Google 地图放在 Android 客户端用户叠加层上。每 30 秒我轮询一次服务器并获取包含用户的 Vector 并将其添加到地图中。

当前状态:
我在一个新线程中使用了所有东西,所以在运行应用程序后我得到:
奇怪的行为(延迟覆盖,多个覆盖),然后用ConcurrentModificationException.
在阅读了一下之后,我发现我需要使用AsyncTask

如果我错了,请纠正我,但我知道在 onCreate 的 Activity 中所做的一切都在 UIhread 中“运行”,所以我需要将“逻辑”(所有网络处理)放在 doInBackground 和所有 UI 处理中,比如把在 onPostExecute 中覆盖在地图上。

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

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

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

2) 是否有具体的 UI 列表可以放入 onPostExecute 或任何概念列表?
在我的情况下,我猜需要将 putNewOnlineUserOnTheMap() 放在 onPostExecute 中。

谢谢。

4

3 回答 3

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。但是之后不要在后台线程中触摸同一个对象。这样您就不需要任何同步,因为在后台线程将其发送出去之后,只有 UI 线程会接触它。(你可以使用一个简单ArrayList的而不是一个Vector

于 2012-04-28T11:51:04.007 回答
1

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

示例:--受保护的类 ParsingTask 扩展 AsyncTask> {

     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();
    }

}
于 2012-04-28T14:12:31.410 回答
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)来实现您的工作。

于 2012-04-28T12:12:39.213 回答