0

I have a problem with using AsyncTask..When I try to use AsyncTask I get error..But when I remove it every thing works fine..Can some one help me abut this?I also searched and find that I must add onpause() but It didnot work.Here is my code

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

}

and here Is error

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

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

}

I already searched and find this similar questions but problem still happens progressdialog-how-to-prevent-leaked-window

Community
  • 1
  • 1
Majid
  • 230
  • 1
  • 5
  • 20
  • 3
    What's there in `main.attachDatabase(selected_databases.get(i));`? – Paresh Mayani Apr 10 '13 at 05:29
  • As this line(java.lang.RuntimeException: An error occured while executing doInBackground()) in the logcat suggests, the problem is in the doInBackground() of AsyncTask. The reason could be that you are trying to create an database handler inside the methods main.emptyDB(); main.creatDB(8); main.attachDatabase(selected_databases.get(i)); from this AsyncTask thread. – SKK Apr 10 '13 at 05:34
  • @PareshMayani I added main.attachDatabase to my question – Majid Apr 10 '13 at 05:36
  • @Santhosh But When I add doInBackground method to a button function It works fine..But When I add It to AsyncTask It get error..I dont think the problem Is with `main.attachDatabase(selected_databases.get(i))` – Majid Apr 10 '13 at 05:38
  • @Majid: because doInBackground doesn't run on UI thread,but onClick() of Button.onClickListener() runs on UI thread. – Mehul Joisar Apr 10 '13 at 05:40
  • @MehulJoisar So I cant use doInBackground in this situation? – Majid Apr 10 '13 at 05:42
  • @Majid: you can use but you can't play with UI while you are in doInBackground() method.if you want to access UI ,you have to use runOnUiThread() method – Mehul Joisar Apr 10 '13 at 05:43
  • @MehulJoisar Now I completly removed Toast from my code but I still get error..Why? – Majid Apr 10 '13 at 05:49
  • @Majid : as the name suggests doInBackground runs on separate thread. In order to have a close connection with activity which called it, you need to pass the context to the AsyncTask. using which you can create the instance of db handler within it. but that is a complex process. as far as i see, if your db you are using is local(sqlite) you don;t need AsyncTask. – SKK Apr 10 '13 at 05:54
  • remove all your UI operations on Asynctask and try.. – AnhSirk Dasarp Apr 10 '13 at 05:55
  • @Majid: your issue is inside persian_poem_class.java at line number 224 – Mehul Joisar Apr 10 '13 at 06:00

3 Answers3

2

It seems you are displaying toast in main.attachDatabase() in doInBackground() which is not possible. That's the reason your getting an exception. doInBackGround() runs in the background thread. You are displaying toast ie updating ui from the background thread.

Return the result in doInBackground(). In onPostExecute() display a toast based on the result.

 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()
  } 
  }
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Now I completly removed Toast from my code but I still get error – Majid Apr 10 '13 at 05:51
  • Yes I get same error..I checked It and I forgot to remove one of toast's in functions..It works fine now..But Why I cant implementing runOnUiThread() in my class?I get undifined error:( – Majid Apr 10 '13 at 06:02
2

There might be an issue due to the Toast you are displaying in catch block inside attachDatabase() method.

Issue:

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

Cover it it by implementing runOnUiThread() if you want to show Toast message whenever you get any exception.

Example:

runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(context, "Hello world", Toast.LENGTH_SHORT).show();
    }
});
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
  • Can you give me an example of implementing runOnUiThread() ..I am new with java :( – Majid Apr 10 '13 at 05:43
  • Now I completly removed Toast from my code but I still get error :( – Majid Apr 10 '13 at 05:49
  • @Majid what is there in `main.creatDB(8);`? You should have posted possible code of every functions. – Paresh Mayani Apr 10 '13 at 05:52
  • i agree with Paresh Mayani. Check every function you call in doInBackground() if they are updating ui. – Raghunandan Apr 10 '13 at 05:59
  • oh sorry It was my mistake..I forgot to remove one of toase's ..Now It works fine..Thanks a lot..But why I want to implementing runOnUiThread() in my class I get The method runOnUiThread(new Runnable(){}) is undefined for the type persian_poem_class ? – Majid Apr 10 '13 at 06:00
  • @Majid read more about: [runOnUiThread()](http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)) – Paresh Mayani Apr 10 '13 at 06:03
  • @PareshMayani Thanks dear freind for your help..I cant accses to android.developer Because "this service is not available in your country." But I searched and find some information abut that – Majid Apr 10 '13 at 06:11
  • @Majid Hmm how strange !! But Stackoverflow is available in whole world ;) – Paresh Mayani Apr 10 '13 at 06:13
  • 2
    @PareshMayani I live in Iran My countries governments make this problem :( Its funny we cant access to many sites (like facebook and ..) because our government blocked them and some sites that we can access ..the site owners and companies blocked our country :((..Anyway..Thanks for your help – Majid Apr 10 '13 at 06:21
1

you are accessing a UI Element in you function that is being called from doinbackground which is not allowed

catch (Exception e) 
    {
        Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
        Log.i("attach_database",e.getMessage());
    }
DeltaCap019
  • 6,532
  • 3
  • 48
  • 70
  • Actually My list consist of chackboxes and I just want to get selected items from list..So I defined an array list and add selected items to it – Majid Apr 10 '13 at 05:51