Android 片段在UI线程上运行吗
我在一个Android 片段在UI线程上运行吗,android,fragment,ui-thread,Android,Fragment,Ui Thread,我在一个ViewPager中加载了一些片段,其中每个“页面”都是从光标中的一行加载的。每个片段显示设备上的图像(JPEG)。当用户删除片段时(即滑动/页面更改、点击后退/后退或完全关闭应用程序),我想调用一个方法,打开JPEG文件进行写入并更新其元数据。实际工作最终由Apache Commons Imaging库处理 我通过从每个片段的生命周期onStop()处理程序调用我的saveToFile()方法实现了这一点这是否意味着整个文件操作最终会在UI线程上运行?我是否应该为此设置一个AsyncT
ViewPager
中加载了一些片段,其中每个“页面”都是从光标中的一行加载的。每个片段显示设备上的图像(JPEG)。当用户删除片段时(即滑动/页面更改、点击后退/后退或完全关闭应用程序),我想调用一个方法,打开JPEG文件进行写入并更新其元数据。实际工作最终由Apache Commons Imaging库处理
我通过从每个片段的生命周期onStop()
处理程序调用我的saveToFile()
方法实现了这一点这是否意味着整个文件操作最终会在UI线程上运行?我是否应该为此设置一个AsyncTask
?
假设文件由于某种原因突然写入(对于某些jpeg)需要很长时间,例如2分钟。那么会发生什么呢?UI会在恢复之前在此页面/片段处等待(冻结)吗?或者该过程(写入文件)是否会以某种方式“在后台”进行?或者进程只是在进程中间被终止、停止
我目前将此连接的方式(onStop
调用saveToFile()
,调用图像库,然后更新文件)似乎正常工作。即使我结束了应用程序,我仍然会看到我的Toast文本弹出,说“写入文件…”似乎这个过程从未被打扰过,我不能说我遇到了任何UI延迟
onStop()处理程序。这是否意味着整个文件操作都结束了
在UI线程上运行?我是否应该为设置一个异步任务
这个
是
AsyncTask有几个部分:实际上在单独线程上运行的doInBackground
方法和在UI线程上运行的onPostExecute
方法
您还可以使用某种观察者模式,例如运行异步并将结果发布到UI
假设文件由于某种原因突然写入(对于某些jpeg)应该 花很长时间(如2分钟)。那么会发生什么呢?用户界面 等一下(别动) 应用程序将崩溃,因为Android将由于ANR(应用程序无响应)而强制关闭它 有关这方面的详细信息,请参阅官方文件: Android应用程序通常完全在单个线程上运行 默认设置为“UI线程”或“主线程”)。这意味着你的一切 应用程序正在UI线程中运行,这需要很长时间才能完成 complete会触发ANR对话框,因为您的应用程序不可用 给自己一个处理输入事件或意图广播的机会 因此,在UI线程中运行的任何方法都应该做得很少 尽可能地在那个线程上工作。特别是,活动应该做什么 尽可能少地设置关键生命周期方法,如 onCreate()和onResume()。可能长时间运行的操作,例如 网络或数据库操作,或计算昂贵 调整位图大小等计算应在辅助进程中完成 线程(或者在数据库操作的情况下,通过异步 请求) 为更长的操作创建工作线程的最有效方法 与AsyncTask类一起使用 以下是我的建议。使用上述EventBus并创建一个
BaseActivity
,它将通过触发一个运行异步的事件来自动为您保存数据onClose()
。然后在需要自动保存功能的所有地方扩展该基本活动
下面是使用EventBus的示例的意思
public abstract class BaseActivity extends Activity{
@Override
protected void onResume(){
if(!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
super.onResume();
}
@Override
protected void onDestroy() {
if(EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this);
super.onDestroy();
}
@Override
protected void onStop() {
super.onStop();
//We fire event and pass the current parent class that inherited this base.
EventBus.getDefault().post(new EventBusProcessMySaveData(this.getClass()));
}
}
//Your model class to use with EventBus
public final class EventBusProcessMySaveData{
private final Class className;
public EventBusProcessMySaveData(final Class className){
this.className = className;
}
public Class getClassName(){
return this.className;
}
}
public class MyMainActivity extends BaseActivity{
//Do you standard setup here onCreate() and such...
//Handle Event for Saving Operation, async.
//This will fire everytime theres an onClose() IN ANY activity that
//extends BaseActivity, but will only process if the class names match.
@Subscribe(threadMode = ThreadMode.ASYNC)
public void methodNameDoesNotReallyMatterHere(final EventBusProcessMySaveData model){
//We make sure this is the intended receiving end by comparing current class name
//with received class name.
if(model.getClassName().equals(this.getClass())){
//Do whatever you need to do that's CPUintensive here.
}
}
}
是的,活动和片段的所有生命周期方法都在主线程(也称为UI线程)上执行。你可以通过在这些方法中使用视图来证实这一点。好的,谢谢。但是,AsyncTask被描述为一个类,用于“执行导致GUI更新的长时间运行的任务”。在我的例子中,我只想在用户实际完成UI后在后台更新文件。当任务未在UI中产生更改时,我是否仍应使用AsyncTask或其他“工作线程”?“当任务未在UI中产生更改时,我是否仍应使用AsyncTask或其他“工作线程”?“-如果不需要与UI对话,则只需启动新的后台线程或工作线程即可。再次参考文档-