简体   繁体   English

android-如何检查后台线程是否成功?

[英]android - How to check if a background thread is successful or not?

I'm trying to extract RAR files with junRAR. 我正在尝试使用junRAR提取RAR文件。 But as I read from this question: OutOfMemoryError when I decompress RAR file on Android , junRAR is not optimized yet for Android. 但是,正如我从以下问题中读到的那样: 在Android上解压缩RAR文件时 ,OutOfMemoryError尚未针对Android优化junRAR。 So, what I want to do is to check if the extraction is successful or not, then give an error message if it fails.(because my app crashes if it the extraction is not successful). 因此,我想做的是检查提取是否成功,如果失败则给出错误消息(因为如果提取失败我的应用程序就会崩溃)。 Can somebody tell me how can I do that checking? 有人可以告诉我如何进行检查吗? My thread is being done here: 我的线程在这里完成:

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();
    }
} 

Here's my Logcat error: 这是我的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 com.android.internal.policy.impl.PhoneWindow$DecorView@41d3a0c0 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 com.android.internal.policy.impl.PhoneWindow$DecorView@41d3a0c0 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)

onPostExecute(Result) invoked on the UI thread after the background computation finishes. 后台计算完成后,在UI thread上调用onPostExecute(Result) The result of the background computation is passed to this method as a parameter. 后台计算的result作为参数传递给此方法。

For more information : http://developer.android.com/reference/android/os/AsyncTask.html 有关更多信息: http : //developer.android.com/reference/android/os/AsyncTask.html

Here is one example 这是一个例子

  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");
  }
}

You can solve this problem using SharedPreferences by creating a SharedPreference file that hold the state of each action you perform on a file using it name as a KEY and a boolean value that describe the state of it either succeeded in extraction or not. 您可以使用SharedPreferences解决此问题,方法是创建一个SharedPreference文件,该文件包含您对文件执行的每个操作的状态,该文件的名称为KEY,而boolean值描述的是提取成功与否的状态。 Also make your method return true if the process succeded and false otherwise. 如果过程成功,还应使您的方法返回true ,否则返回false

Modify your constructor as the following to save the context of the app 如下修改您的构造函数以保存应用程序的上下文

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

Replace your doInBackground method with this one: 用此方法替换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;
}    

More info about SharedPReference in this LINK 在此LINK中有关SharedPReference更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM