2017-07-06 55 views
2

运行我有一个ViewPager,其中每个“页”是从一排装在一个光标加载一些片段。每个片段在设备上显示图像(JPEG)。当用户退出片段(即刷卡/换页,打回/,或者只是关闭应用程序完全)我要调用一个打开JPEG文件进行写入和执行其元数据的更新的方法。实际工作最终由Apache Commons Imaging库处理。是否片段的onStop在UI线程

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

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

目前我有这种方法(onStop调用saveToFile(),调用映像库,然后更新文件)的方式似乎按照它应该的方式工作。即使我结束应用程序,我仍然会看到我的Toast文本弹出,并显示“写入文件...”看起来,这个过程从未受到干扰,而且我不能说我遇到了任何UI延迟。

+0

是活性片段的所有生命周期方法是在主线程(又名UI线程)来执行。你可以通过这些方法来玩视图来确认它。 – Sufian

回答

2

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

YES

一种的AsyncTask由几个部分组成:一个doInBackground方法,做,事实上,在一个单独的线程中运行,并且在UI线程上运行onPostExecute方法。

您还可以使用某种形式的观察者模式,如EventBus的运行异步和后结果的UI。


说由于某种原因突然(某些JPEG)文件写入应 需要很长的时间,例如2分钟。那么会发生什么? UI 只是等待(冻结)

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

请参考官方文档的详细信息,这一点:https://developer.android.com/training/articles/perf-anr.html

Android应用程序通常完全在单个线程的运行 默认“UI线程”或“主线程”)。这意味着任何你的 应用程序正在UI线程中做的事情需要很长时间 完整的可以触发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. 
     } 
    } 

} 
+0

对,谢谢。但是,AsyncTask被描述为一个类,“执行长时间运行的任务会导致更新GUI。”在我的情况下,我只想在后台更新文件,在用户实际上完成了UI之后。当任务不会在UI中产生更改时,是否仍应使用AsyncTask或其他“工作线程”? – joakimk

+0

“当任务没有在UI中产生变化时,我还应该使用AsyncTask还是使用其他”工作线程“?” - 如果您不需要与UI交谈,那么只需旋转一个新的后台线程或工作者线程。再次参阅文档 - https://developer.android.com/guide/components/processes-and-threads.html – Dayan

+0

是的,再次感谢!这听起来像我所需要的。 – joakimk