目标:
使用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中。
感谢。
答案 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)来实现您的工作。