Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 片段在UI线程上运行吗_Android_Fragment_Ui Thread - Fatal编程技术网

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对话,则只需启动新的后台线程或工作线程即可。再次参考文档-