当前位置: 首页 > 知识库问答 >
问题:

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

苗征
2023-03-14

我正在尝试使用JunRAR提取RAR文件。但正如我从这个问题中读到的:OutOfMemoryError当我在Android上解压缩RAR文件时,JunRAR尚未针对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 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)

共有2个答案

裴弘
2023-03-14

您可以使用SharedReferences解决此问题,方法是创建一个SharedReference文件,该文件保存您在文件上执行的每个操作的状态,该文件使用文件名作为键,并创建一个描述提取成功与否的布尔值。如果过程成功,请使方法返回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;
}    

有关此LINK中SharedP参考的更多信息

东门茂实
2023-03-14

后台计算完成后,在UI线程上调用onPostExecute(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");
  }
}
 类似资料:
  • 本文向大家介绍如何在C#中检查线程是否为后台线程,包括了如何在C#中检查线程是否为后台线程的使用技巧和注意事项,需要的朋友参考一下 要检查线程是否是后台线程,代码如下: 示例 输出结果 这将产生以下输出- 示例 让我们看另一个例子- 输出结果 这将产生以下输出-

  • 我需要检查运行某段代码的线程是否是主(UI)线程。我怎样才能做到这一点呢?

  • 问题内容: 好吧,我是SQL的新手,我刚刚读到,存储过程始终返回一个值,确定该过程中的查询是否已成功执行是一种很好的做法。 所以我有一个带有select语句的简单存储过程,如果要执行,我想返回1,否则返回-1。 您能告诉我如何用SQL编写该条件吗? 如果有关系,我的数据库是MS SQL Server。 谢谢你。 问题答案: 使用输出参数返回成功状态以及Try..Catch块

  • 本文向大家介绍如何检查iOS程序是在前台还是在后台?,包括了如何检查iOS程序是在前台还是在后台?的使用技巧和注意事项,需要的朋友参考一下 作为iOS开发人员,了解应用程序处于前台还是后台很重要,我们需要处理多个事件,例如后台下载,应用程序进入前台时的事件。 在这里,我们将看到如何检查应用程序是在后台还是在前台。 我们将为此使用通知中心, 要了解更多信息,请参考Apple文档。  https://

  • 问题内容: 有什么方法可以检查给定线程是否正在休眠? 问题答案: 您可以呼叫并检查状态是否为。 请注意,但这并不一定意味着调用的线程也可能正在调用中或其他类似的事件中等待。

  • 如何检查当前线程是否是Linux上的主线程?看起来gettid()只返回一个pid,但linux似乎并不保证main()的线程总是具有一个常量和统一的pid。 这样做的原因是,我正在进行自动并行化,并且我希望确保pthread_create()不会在已经运行在pthread_create()创建的线程上的函数中调用。