这是我的应用程序的基本生命周期。 它现在的目标SDK版本8,因为我仍然在运行我的设备上的Android 2.3.3。
- 应用程序启动后
onResume()
被调用
该方法show()
被调用以显示高速缓存的数据。 - 后台服务得到启动,其下载和存储数据。 它使用
AsyncTask
实例来完成其工作。 - 其中一个任务商店在SQLite数据库下载数据。
- 广播意图在发送
onPostExecute()
当存储的任务已经完成。 - 该
MapActivity
接收的意图和处理它。
该方法show()
被调用以显示缓存和新的数据。
在这个方法中show()
覆盖已经加入后,地图视图获取无效 。 当这工作正常show()
已经从MapActivity本身调用。 它引发了异常 ,然而,当asynchonous任务是方法调用(间接地)的源极。
据我了解,我在UI线程 ,当我触发show()
在这两种情况下。 这是真的?
public class CustomMapActivity extends MapChangeActivity {
private boolean showIsActive = false;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(IntentActions.FINISHED_STORING)) {
onFinishedStoring(intent);
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(mReceiver, new IntentFilter(IntentActions.FINISHED_STORING));
}
@Override
protected void onResume() {
super.onResume();
show();
}
@Override
protected void onMapZoomPan() {
loadData();
show();
}
@Override
protected void onMapPan() {
loadData();
show();
}
@Override
protected void onMapZoom() {
loadData();
show();
}
private void onFinishedStoring(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
boolean success = extras.getBoolean(BundleKeys.STORING_STATE);
if (success) {
show();
}
}
private void loadData() {
// Downloads data in a AsyncTask
// Stores data in AsyncTask
}
private void show() {
if (showIsActive) {
return;
}
showIsActive = true;
Uri uri = UriHelper.getUri();
if (uri == null) {
showIsActive = false;
return;
}
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
List<Overlay> mapOverlays = mapView.getOverlays();
CustomItemizedOverlay overlay = ItemizedOverlayFactory.getCustomizedOverlay(this, cursor);
if (overlay != null) {
mapOverlays.clear();
mapOverlays.add(overlay);
}
}
cursor.close();
mapView.invalidate(); // throws CalledFromWrongThreadException
showIsActive = false;
}
}
这里是堆栈跟踪...
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRoot.checkThread(ViewRoot.java:3020)
at android.view.ViewRoot.invalidateChild(ViewRoot.java:647)
at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:673)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
at android.view.View.invalidate(View.java:5332)
at info.metadude.trees.activities.CustomMapActivity.showTrees(CustomMapActivity.java:278)
at info.metadude.trees.activities.CustomMapActivity.onMapPan(CustomMapActivity.java:126)
at info.metadude.trees.activities.MapChangeActivity$MapViewChangeListener.onChange(MapChangeActivity.java:50)
at com.bricolsoftconsulting.mapchange.MyMapView$1.run(MyMapView.java:131)
at java.util.Timer$TimerImpl.run(Timer.java:284)
注:我用的是MapChange项目,以在地图上的事件接收通知。
编辑:
从我现在在阅读有关的AsyncTask文件 (向下滚动了一下),我不知道如果我使用它的正确方法。 正如前面提到的,我开始AsyncTask
从内实例Service
类。 在相反,文档指出...
的AsyncTask允许您在用户界面上执行异步工作。 它在辅助线程执行阻塞操作,然后发布在UI线程上的结果,而不需要你来处理线程和/或处理自己。
......这听起来仿佛AsyncTask
应该只在内部使用Activity
不是内Service
!