百度Frontia应用数据存储在后台运行不起来

通过百度Frontia sdk的应用数据存储功能,从云存储下载或上传文件,百度提供的Demo是正常的。

但是加到自己的代码中就不能运行,后来发现,自己的代码是在后台运行的,Frontia Demo是在前台运行的。


原因是mCloudStorage.downloadFile()会创建Handler,而创建Handler是需要Looper消息循环来初始化的。如果在自己的子线程中调用mCloudStorage.downloadFile(),这个子线程是没有Lopper消息循环的,自然就创建不了Handler,直接报错:

03-28 12:40:29.120: E/AndroidRuntime(21077): FATAL EXCEPTION: Thread-6094

03-28 12:40:29.120: E/AndroidRuntime(21077): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-28 12:40:29.120: E/AndroidRuntime(21077):  at android.os.Handler.<init>(Handler.java:121)
03-28 12:40:29.120: E/AndroidRuntime(21077):  at com.baidu.frontia.base.taskqueue.QueuedAsyncTaskHelper.<init>(SourceFile:71)
03-28 12:40:29.120: E/AndroidRuntime(21077):  at com.baidu.frontia.base.taskqueue.QueuedAsyncTaskHelper.instance(SourceFile:46)
03-28 12:40:29.120: E/AndroidRuntime(21077):  at com.baidu.frontia.module.storage.bcs.FrontiaBCSImpl.downloadFile(SourceFile:133)
03-28 12:40:29.120: E/AndroidRuntime(21077):  at com.baidu.frontia.api.FrontiaStorage.downloadFile(Unknown Source)

03-28 12:40:29.120: E/AndroidRuntime(21077):  at com.hugedata.speedometer.AppFileActivity$1LooperThread.run(AppFileActivity.java:152)


也就是说,子线程默认没有Looper,连Handler都创建不了。

解决方法,添加Looper:

注意示例代码中Looper.prepare();      Looper.myLooper().quit();   Looper.loop();这三句的位置:

  class LooperThread extends Thread
 {
     public void run() 
     {
         FileUtils.deleteFile(LOCAL_FILE_NAME);
         Looper.prepare();           
         final long startTime = System.currentTimeMillis();
         
         //三个参数
         mCloudStorage.downloadFile(mFile, 
                 new FileProgressListener() {
                     @Override
                     public void onProgress(String source, long allReadedLen, long total) {
 
           
                     }
                  }, 
                 new FileTransferListener() {
           
                     @Override
                     public void onSuccess(String source, String newTargetName) {
      
                         mSuccess = true;
                         synchronized(mFile) {
                             mFile.notify();
                         }                         
                         Looper.myLooper().quit();
                     }
           
                     @Override
                     public void onFailure(String source, int errCode, String errMsg) {
                         
                         Looper.myLooper().quit();
                         synchronized(mFile) {
                             mFile.notify();
                         }
                         mSuccess = false;
                     }
           
                 });
         
         Looper.loop();
     }
 }
 
 private boolean doDownloadFromBaiduCloud() {
     
     new LooperThread().start();
     
     synchronized(mFile) {
           try {
                 mFile.wait();  //这里仅仅借用mFile作为同步锁,无它意
                 Logger.d("------------------------after wait-----mSuccess:" + mSuccess);
             }
             catch (InterruptedException e) {
                 e.printStackTrace();
         }  
     }

上面的方式只能执行一次,LooperThread线程退出后,再重新new一个LooperThread执行就会在 mCloudStorage.downloadFile()阻塞,原因是mCloudStorage持有的是用上一个thread 的Looper初始化的,而这个Looper已经quit了,不再looper了!

解决方法:不要每次都new一个LooperThread,全局只要一个就OK,然后自己new一个Handler,所有的任务都post过去,这样就做到了Looper不退出,FrontiaStorage内部new 出的Handler始终跑在这个Looper上:

class LooperThread extends Thread{
    private Handler mExecuteHandler = null;

    public void addTask(Rnnable task){
        mExecuteHandler.post(task);
    }

    public void run(){
        Looper.prepare();
        mExeucteHandler = new Handler();
        Looper.loop();
    }
}






你可能感兴趣的:(百度Frontia应用数据存储在后台运行不起来)