2017-07-06 54 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