片段onStop是否在UI线程上运行

时间:2017-07-06 13:19:41

标签: android fragment ui-thread

我在ViewPager中加载了一些片段,其中每个“页面”都从光标中的一行加载。每个片段在设备上显示图像(JPEG)。当用户解散片段时(即滑动/页面更改,回击/向上或完全关闭应用程序),我想调用一个方法打开JPEG文件进行写入并更新其元数据。实际工作最终由Apache Commons Imaging库处理。

我已经通过从每个片段的生命周期saveToFile()处理程序调用我的onStop()方法来实现这一点。 这是否意味着整个文件操作最终在UI线程上运行?我应该为此设置AsyncTask吗?

由于某种原因突然(对于某些jpeg)说文件写入需要很长时间,例如2分钟。然后会发生什么? UI会在恢复之前等待(冻结)此页面/片段吗?或者进程(写入文件)会以某种方式“在后台”进行?或者这个过程是否会被杀死,中途停止?

我当前有线连接的方式(onStop调用saveToFile(),调用映像库然后更新文件)似乎应该正常工作。即使我结束了应用程序,我仍然看到我的Toast文本突然出现,说“写入文件......”看起来,这个过程从未受到干扰,我不能说我遇到任何UI延迟。

1 个答案:

答案 0 :(得分:2)

  

onStop()处理程序。这是否意味着整个文件操作结束   在UI线程上运行?我应该确定为AsyncTask设置   此?

AsyncTask有几个部分:一个doInBackground方法实际上在一个单独的线程上运行,而onPostExecute方法在UI线程上运行。

您还可以使用某种观察者模式(例如EventBus)来运行异步并将结果发布到UI。

  

由于某种原因突然(对某些jpeg)说文件写应该   需要很长时间,例如2分钟。然后会发生什么? UI会吗?   等待(冻结)

应用程序将崩溃,因为Android会因ANR(应用程序无响应)而强制关闭它。

有关详细信息,请参阅官方文档:https://developer.android.com/training/articles/perf-anr.html

  

Android应用程序通常完全在单个线程上运行   默认为“UI线程”或“主线程”)。这意味着什么   应用程序正在UI线程中进行,需要很长时间   完成可以触发ANR对话框,因为您的应用程序不是   给自己一个处理输入事件或意图广播的机会。

     

因此,在UI线程中运行的任何方法都应该尽可能少   尽可能在该线程上工作。特别是,活动应该做   尽可能少地设置关键的生命周期方法,如   onCreate()和onResume()。可能长时间运行的操作如   网络或数据库操作,或计算上昂贵   调整位图大小等计算应该在worker中完成   线程(或者在数据库操作的情况下,通过异步   请求)。

     

为更长时间的操作创建工作线程的最有效方法   与AsyncTask类有关。

这是我推荐的。使用上面提到的EventBus并创建一个BaseActivity,它将通过触发运行Async的事件自动为您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.
        }
    }

}