将这些事情整合在一起我有一个棘手的问题。 示例:我想获取用户位置并使用纬度和经度值更新UI。因为我坚持使用MVC模式,所以我已经为此任务创建了一个单独的类(例如LocationWorker)并按照本指南实现了它: http://developer.android.com/training/location/retrie ..
问题:在这种情况下,onConnected回调位于LocationWorker类中,无法与UI通信。我试图在MainActivity类中实现onConnected callBack(也为GoogleApiClient.ConnectionCallbacks添加实现),但是我得到一个错误(尝试在空对象引用上调用虚方法' methodName')。似乎在Worker实际完成所有工作之前执行了回调(在连接之后它获取用户位置,但OnConnectedCallback在连接之后以及在它有任何时间获取任何数据之前被触发)。
无论如何,对我来说这是一个很大的问题,我应该使用什么才能拥有异步任务,并且能够在完成异步任务时更新UI(并且不要破坏MVC)?
答案 0 :(得分:0)
AsyncTask中有一个get(),它将在请求完成时触发,并返回您在创建AsyncTask时指定的RETURN TYPE。
eg : ImageGrabber extends AsyncTask<String, String, Bitmap>
这里的返回类型是Bitmap
所以这里有一个示例,下面的字符串将包含响应。
String jsonResponse = new JSONHelper().execute("http://example.com").get();
答案 1 :(得分:0)
异步类:
//We can attach any object to the async class for result
private class MyAsyncTask extends AsyncTask<Void,MyObject,MyObject >{
@Override
protected MyObject doInBackground(Void... params) {
//Do the work to get your data
//this is done in a background thread
//prepare the result
//MyObject object = new MyObject();
//object.setLong(LONG);
//object.setLang(LANG);
//You can pass the result here
//return object;
return null;
}
@Override
protected void onPostExecute(MyObject object) {
super.onPostExecute(object);
//Update UI
//this is done on the main thread
//access data from the Object result
//object.getLong();
//object.getLang();
}
}
启动异步类:
new MyAsyncTask().execute();
答案 2 :(得分:0)
如果您想简化用户界面和任何任务之间的沟通,我建议您使用此框架将您的任务与用户界面分离:Greenrobot's EventBus
只需最少的学习曲线,您就可以通过事件总线完成您想要完成的任务。
您的UI将订阅您的任务发布的事件:
public class LocationEvent {
private float lat, lng;
public LocationEvent(float lat, float lng) { this.lat=lat; this.lng=lng; }
}
MainActivity {
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
public void onEvent(LocationEvent event) {
// update user location
}
}
LocationWorker {
void doSomething() {
eventBus.post(new LocationEvent(lat, lng));
}
}
使用作业队列而不是AsyncTask将使您的任务/作业更容易管理,并具有重试和持久性的额外好处。
看看Path's Android Priority Job Queue
答案 3 :(得分:0)
EventBus看起来很有希望。
另一种选择是使用意图和广播接收器。
示例:
在MainActivity.java中:
@Override
public void onResume() {
super.onResume();
IntentFilter iFilter= new IntentFilter("updatelocation");
iFilter.addAction("someOtherAction"); //if you want to add other actions to filter
this.registerReceiver(br, iFilter);
}
@Override
public void onPause() {
this.unregisterReceiver(br);
super.onPause();
}
private BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("UpdateLocation")){
//set these to member variables for later retrieval
double lat = intent.getExtras().getDouble("lat");
double lon = intent.getExtras().getDouble("lon");
this.runOnUiThread(mUpdateLocation);
}
}
};
private final Runnable mUpdateLocation = new Runnable() {
@Override
public void run() {
//TODO: Update your UI here
}
};
然后,在LocationWorker类中,在位置发生更改时发送意图。确保您在LocationWorker类中引用了应用程序上下文。
请参阅此帖子:passing GPS coordinates to activity
//Make sure you have a reference to the application context
Intent updateLocation= new Intent(context, MainActivity.class);
updateLocation.setAction("UpdateLocation");
updateLocation.putExtra("lon", xLocation.getLongitude());
updateLocation.putExtra("lat", xLocation.getLatitude());
context.sendBroadcast(i);
答案 4 :(得分:0)
使用new Asynctaskname.execute().get();
它将首先完成异步任务,然后执行下一个。