在我的活动中不能使用AsyncTask

时间:2013-04-10 05:27:08

标签: android android-asynctask

我在使用AsyncTask时遇到问题。当我尝试使用AsyncTask时,我收到错误。但是当我删除它时,每件事情都可以正常工作。有人可以帮我解决这个问题吗?我也搜索了发现我必须添加onpause()但它没有用。这是我的代码

package co.tosca.persianpoem;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class Database_list extends Activity {

    persian_poem_class main=new persian_poem_class(this);
    public List<String> selected_databases = new ArrayList<String>();
    public ProgressDialog pd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_database_list);
        File path=new File(ClubCP.SDcardPath+"/temp/database/");
        List<String>file_lists =    main.directoryPath(path,false);
        Log.i("file_list",file_lists.toString());
        ListView Database_list=(ListView)findViewById(R.id.database_list);
        final InteractiveArrayAdapter arrayadapter=new InteractiveArrayAdapter(this,file_lists);
        Database_list.setAdapter(arrayadapter);
        Button build =(Button)findViewById(R.id.btn_build_database);
        build.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                selected_databases=arrayadapter.getSelectedItems();
                if(selected_databases.isEmpty()!=true){
                    new bulid_database().execute();

                }
                else{
                    Toast.makeText(Database_list.this, "At least select one database", 1).show();
                }
            }
        });
    }
    @Override
    public void onPause()
    {
        super.onPause();
        if(pd != null)
            pd.dismiss();
    }
    private class bulid_database extends AsyncTask<String, Long, Void> {

        // Begin - can use UI thread here
        protected void onPreExecute() {
              pd = ProgressDialog.show(Database_list.this,"","Please wait...", true,false);
        }
        // this is the SLOW background thread taking care of heavy tasks
        // cannot directly change UI
        protected Void doInBackground(final String... args) {
            // simulate here the slow activity
            main.emptyDB();
            main.creatDB(8);
            for (int i =0; i < selected_databases.size(); i++) {


                main.attachDatabase(selected_databases.get(i));
                //publishProgress((long)i);
            }
                return null;
                }
        // periodic updates - it is OK to change UI
        @Override
        protected void onProgressUpdate(Long... value) {
            pd.setMessage("still working");
        }
        // End - can use UI thread here
        protected void onPostExecute(final Void unused) {
            if (pd!=null) {
                pd.dismiss();
                }
        }
        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.database_list, menu);
        return true;
    }

}

这里是错误

04-10 09:39:15.467: W/dalvikvm(3411): threadid=12: thread exiting with uncaught exception (group=0x2b542210)
04-10 09:39:15.497: E/AndroidRuntime(3411): FATAL EXCEPTION: AsyncTask #1
04-10 09:39:15.497: E/AndroidRuntime(3411): java.lang.RuntimeException: An error occured while executing doInBackground()
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.lang.Thread.run(Thread.java:856)
04-10 09:39:15.497: E/AndroidRuntime(3411): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.os.Handler.<init>(Handler.java:121)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.widget.Toast$TN.<init>(Toast.java:317)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.widget.Toast.<init>(Toast.java:91)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.widget.Toast.makeText(Toast.java:233)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at co.tosca.persianpoem.persian_poem_class.creatDB(persian_poem_class.java:224)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at co.tosca.persianpoem.Database_list$bulid_database.doInBackground(Database_list.java:65)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at co.tosca.persianpoem.Database_list$bulid_database.doInBackground(Database_list.java:1)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
04-10 09:39:15.497: E/AndroidRuntime(3411):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-10 09:39:15.497: E/AndroidRuntime(3411):     ... 5 more

这里是attach_database

public void attachDatabase(String database_name){
     Log.i("attach_database",database_name);
    //closeMyDb();
    //openMyDb();
     Db.close();
     Db = SQLiteDatabase.openDatabase(ClubCP.DbPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
    try{
    String sql="attach '"+ClubCP.SDcardPath+"/temp/database/"+database_name+"' as toMerge; insert into cat select * from toMerge.cat; insert into poem select * from toMerge.poem; insert into verse select * from toMerge.verse; insert into poet select * from toMerge.poet;detach database toMerge;";
     String[] queries = sql.split(";");

          for(String query : queries){
              Db.execSQL(query);
          }
     Db.close();
    }
    catch (Exception e) 
    {
        Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
        Log.i("attach_database",e.getMessage());
    }

}

我已经搜索并找到了类似的问题,但问题仍然存在 progressdialog-how-to-prevent-leaked-window

3 个答案:

答案 0 :(得分:2)

似乎你在doInBackground()中的main.attachDatabase()中显示toast,这是不可能的。这就是你获得例外的原因。 doInBackGround()在后台线程中运行。您正在显示toast,即从后台线程更新ui。

在doInBackground()中返回结果。在onPostExecute()中,根据结果显示一个toast。

 class TheTask extends AsyncTask<Void,Void,Void>
 {
    protected void onPreExecute()
     {
     //display progressdialog.
     } 

  protected void doInBackground(Void ...params)//return result here  
{  
//http request. do not update ui here

return null;
 } 

protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
{     
    super.onPostExecute(result);
    //dismiss progressdialog.
    //update ui using the result returned form doInbackground()
  } 
  }

答案 1 :(得分:2)

由于您在Toast方法catch区块中显示的attachDatabase(),可能会出现问题。

<强>问题:

 catch (Exception e) 
    {
        Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
        Log.i("attach_database",e.getMessage());
    }

如果您希望在出现任何异常时显示Toast消息,请执行runOnUiThread()以覆盖它。

示例:

runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(context, "Hello world", Toast.LENGTH_SHORT).show();
    }
});

答案 2 :(得分:1)

您正在访问正在从UI调用的函数中的doinbackground元素,这是不允许的

catch (Exception e) 
    {
        Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
        Log.i("attach_database",e.getMessage());
    }