2014-03-02 24 views
1

我想用junRAR提取RAR文件。但是當我從這個問題中讀到:OutOfMemoryError when I decompress RAR file on Android,junRAR尚未針對Android進行優化。所以,我想要做的是檢查提取是否成功,然後在失敗時提供錯誤消息(因爲如果提取不成功,我的應用程序崩潰)。有人可以告訴我,我該怎麼做,檢查?我的線程正在這裏做:android-如何檢查後臺線程是否成功?

public class MyTask extends AsyncTask<Void, Void, Void> { 

    private ProgressDialog progress; 
    public MyTask(ProgressDialog progress) { 
     this.progress = progress; 
    } 

    public void onPreExecute() { 
    progress.show(); 
    }  
@Override 
protected Void doInBackground(Void... params) { 
    if(taskType==1){ 
     extractArchive(rarFile, destinationFolder);    
    } 
return null; 
} 

public void onPostExecute(Void unused) { 
    progress.dismiss(); 
    if(taskType==1){ 
     refreshFileList(); 
     Toast.makeText(MainActivity.this, "Extracted to " + targetPath, Toast.LENGTH_LONG).show(); 
    } 
} 

這裏是我的logcat錯誤:

 

03-02 16:59:40.777: E/AndroidRuntime(28573): FATAL EXCEPTION: AsyncTask #1 
03-02 16:59:40.777: E/AndroidRuntime(28573): java.lang.RuntimeException: An error occured while executing doInBackground() 
03-02 16:59:40.777: E/AndroidRuntime(28573): at android.os.AsyncTask$3.done(AsyncTask.java:278) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.lang.Thread.run(Thread.java:856) 
03-02 16:59:40.777: E/AndroidRuntime(28573): Caused by: java.lang.OutOfMemoryError 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.unpack.ppm.SubAllocator.startSubAllocator(SubAllocator.java:146) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.unpack.ppm.ModelPPM.decodeInit(ModelPPM.java:216) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.unpack.Unpack.readTables(Unpack.java:656) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.unpack.Unpack.unpack29(Unpack.java:165) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.unpack.Unpack.doUnpack(Unpack.java:120) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.Archive.doExtractFile(Archive.java:501) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.github.junrar.Archive.extractFile(Archive.java:443) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.jearom.thesisfmanager.MainActivity.extractArchive(MainActivity.java:2270) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.jearom.thesisfmanager.MainActivity$MyTask.doInBackground(MainActivity.java:1962) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at com.jearom.thesisfmanager.MainActivity$MyTask.doInBackground(MainActivity.java:1) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at android.os.AsyncTask$2.call(AsyncTask.java:264) 
03-02 16:59:40.777: E/AndroidRuntime(28573): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
03-02 16:59:40.777: E/AndroidRuntime(28573): ... 5 more 
03-02 16:59:41.437: E/WindowManager(28573): Activity com.jearom.thesisfmanager.MainActivity has leaked window [email protected] that was originally added here 
03-02 16:59:41.437: E/WindowManager(28573): android.view.WindowLeaked: Activity com.jearom.thesisfmanager.MainActivity has leaked window [email protected] that was originally added here 
03-02 16:59:41.437: E/WindowManager(28573):  at android.view.ViewRootImpl.(ViewRootImpl.java:344) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.view.Window$LocalWindowManager.addView(Window.java:537) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.app.Dialog.show(Dialog.java:278) 
03-02 16:59:41.437: E/WindowManager(28573):  at com.jearom.thesisfmanager.MainActivity$MyTask.onPreExecute(MainActivity.java:1867) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.os.AsyncTask.execute(AsyncTask.java:511) 
03-02 16:59:41.437: E/WindowManager(28573):  at com.jearom.thesisfmanager.MainActivity$6.onClick(MainActivity.java:752) 
03-02 16:59:41.437: E/WindowManager(28573):  at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.os.Handler.dispatchMessage(Handler.java:99) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.os.Looper.loop(Looper.java:137) 
03-02 16:59:41.437: E/WindowManager(28573):  at android.app.ActivityThread.main(ActivityThread.java:4456) 
03-02 16:59:41.437: E/WindowManager(28573):  at java.lang.reflect.Method.invokeNative(Native Method) 
03-02 16:59:41.437: E/WindowManager(28573):  at java.lang.reflect.Method.invoke(Method.java:511) 
03-02 16:59:41.437: E/WindowManager(28573):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787) 
03-02 16:59:41.437: E/WindowManager(28573):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554) 
03-02 16:59:41.437: E/WindowManager(28573):  at dalvik.system.NativeStart.main(Native Method) 

+0

看在這個鏈接:也許它會幫助你 http://stackoverflow.com/questions/13694850/java-start-one-background-thread-after-another-complete – GigantoMK

+0

發佈完整的stacktrace不僅僅是1行,而且你需要'doInbackground()中的return語句' – Raghunandan

+0

您在MainActivity.java:2270上分配的內存太多了。也儘量不要有這樣的大類,重構。 – m0skit0

回答

1

onPostExecute(結果)的後臺計算結束後的UI thread調用。後臺計算的result作爲參數傳遞給此方法。

欲瞭解更多信息:http://developer.android.com/reference/android/os/AsyncTask.html

下面是一個例子

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
    int count = urls.length; 
    long totalSize = 0; 
    for (int i = 0; i < count; i++) { 
     totalSize += Downloader.downloadFile(urls[i]); 
     publishProgress((int) ((i/(float) count) * 100)); 
     // Escape early if cancel() is called 
     if (isCancelled()) break; 
    } 
    return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
    setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
    showDialog("Downloaded " + result + " bytes"); 
    } 
} 
+0

我已經在使用onPostExecute(Result),但問題是我的應用程序在doInBackground階段崩潰,所以我在想的是在doInBackground階段檢查提取是否沒有錯誤。 –

+0

@The_Student然後發佈你的logcat。 –

+0

Here: 03-02 16:59:40.777:E/AndroidRuntime(28573):致命異常:AsyncTask#1 03-02 16:59:40.777:E/AndroidRuntime(28573):java.lang.RuntimeException:An在執行doInBackground()發生錯誤 03-02 16:59:40.777:E/AndroidRuntime(28573):\t在android.os.AsyncTask $ 3.done(AsyncTask.java:278) –

0

您可以通過創建一個SharedPreference文件保存每個動作,你用它在文件上執行國家解決使用SharedPreferences這個問題名稱作爲KEY和描述其狀態的值,或者成功提取或不提取。如果過程成功,也會使您的方法返回true,否則返回false

修改你的構造爲以下保存應用程序的情況下

private ProgressDialog progress; 
private Context mContext; 
public MyTask(ProgressDialog progress, Context context) { 
    this.progress = progress; 
    this.mContext = context; 
} 

替換爲您doInBackground方法這一個:

@Override 
protected Void doInBackground(Void... params) { 
if(taskType==1){ 
    if(extractArchive(rarFile, destinationFolder)){ 
     SharedPreferences myLog = mContext.getSharedPreferences("state_holder", Context.MODE_PRIVATE); 
     SharedPreferences.Editor editor = myLog.edit(); 
     editor.putBoolean("file_name", true); 
     editor.commit(); 
    }    
} 
return null; 
}  

更多信息有關SharedPReference在這個LINK

+0

讓我試試這個方法。如果它有效,我會回到這裏。謝謝。 –

+0

我想我不能將這種方法應用於我的代碼。你能幫助我如何在我的代碼上應用相同的方法?我在這個問題上更新我的代碼。 –

+0

好吧,等我爲你創建這個修改 –