问题描述
下面是我的应用程序的基本生命周期。它现在的目标SDK版本8,因为我还在我的设备上运行Android 2.3.3。
Here is the basic life cycle of my application. It targets SDK version 8 by now, since I am still running Android 2.3.3 on my device.
- 应用程序启动时,
onResume()
是所谓的结果
该方法显示()
被称为显示缓存的数据。 - 后台服务得到启动其下载和存储数据。它采用
的AsyncTask
实例来完成其工作。 - 一个任务商店在SQLite数据库中下载的数据。
- 广播意图在
onPostExecute发送()
当存储的任务已经完成。 - 的
MapActivity
接收的意图和处理它。结果
该方法显示()
被称为显示缓存和新的数据。
- The application starts,
onResume()
is called
The methodshow()
is called to display cached data. - A background service gets started which downloads and stores data. It uses
AsyncTask
instances to accomplish its work. - One of the tasks stores downloaded data in a SQLite database.
- A broadcast intent is sent in
onPostExecute()
when the storing task has finished. - The
MapActivity
receives the intent and handles it.
The methodshow()
is called to display cached and new data.
在该方法显示()
地图上看得到的无效覆盖已添加之后。这工作得很好,当显示()
已从MapActivity本身调用。它的引发了一个异常,然而,当asynchonous任务的方法调用(间接)的源
Within the method show()
the map view gets invalidated after the overlay has been added. This works fine when show()
has been called from the MapActivity itself. It raises an exception, however, when the asynchonous task is the source of the method call (indirectly).
据我了解,我在这两种情况下的 UI线程当我触发显示()
。这是真的吗?
As far as I understand, I am at the UI thread when I trigger show()
in both cases. Is this true?
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;
}
}
下面是堆栈跟踪...
Here is the stack trace ...
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)
请注意:我使用的项目,以便接收地图事件的通知
Note: I use the MapChange project in order to receive notifications on map events.
编辑:
从我现在阅读文档中有关的AsyncTask (向下滚动了一下),我不知道如果我使用它的正确方法。从服务
类中为previously提到我开始的AsyncTask
实例。在相反,文档指出...
的AsyncTask允许您在用户界面上执行异步工作。它在辅助线程执行阻塞操作,然后发布在UI线程上的结果,而不需要您自己处理线程和/或处理程序。
......这听起来好像的AsyncTask
只应活动中使用
A <$ C内不$ C>服务?!
... which sounds as if AsyncTask
should only be used within an Activity
not within a Service
?!
推荐答案
每个定时器有哪些任务顺序执行一个线程。当这个线程繁忙运行任务,可运行的任务可能会受到延迟。
这篇关于安卓:CalledFromWrongThreadException当广播意图处理抛出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!