12

Sometimes i get this crash error in my app

java.lang.RuntimeException: An error occured while executing doInBackground()

This is the full logCat:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast.<init>(Toast.java:68)
at android.widget.Toast.makeText(Toast.java:231)
at kostas.menu.olympiakos.nea.loadFeed(nea.java:84)
at kostas.menu.olympiakos.nea.access$1(nea.java:75)
at kostas.menu.olympiakos.nea$BackgroundAsyncTask_nea.doInBackground(nea.java:242)
at kostas.menu.olympiakos.nea$BackgroundAsyncTask_nea.doInBackground(nea.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
... 4 more

and this is my .nea class code:

package kostas.menu.olympiakos;


import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;


public class nea extends ListActivity{
    private List<Message> messages; 




    List<String> des = new ArrayList<String>();//to prosthesa gia na anoigei to keimeno sto alert
    List<String> text = new ArrayList<String>();//to prosthesa gia na anoigei o titlos sto alert
    List<URL> url = new ArrayList<URL>();//to prosthesa gia to koumpi pou pigainei sto link

    List<String> imgl = new ArrayList<String>();//to prosthesa gia na anoigei to keimeno sto alert

    @Override 
    public void onCreate(Bundle icicle) {   
        super.onCreate(icicle);
        setContentView(R.layout.main2);

        if(isInternetOn()) {
            new BackgroundAsyncTask_nea().execute();
            }else{
             Toast.makeText(nea.this,R.string.no_connection, Toast.LENGTH_SHORT).show();
             finish();
            }



    }


    private void loadFeed(AsyncTask<Void, Void, Void> asyncTask){
        try{ 
            BaseFeedParser parser = new BaseFeedParser();
            messages = parser.parse();

            }
         catch (Throwable t){
              Log.e("OSFP.News",t.getMessage(),t);

                Toast.makeText(nea.this, "Χρειάζεστε σύνδεση στο internet",
                        Toast.LENGTH_SHORT).show();
                finish();

            }
    }


    private void displayRss(){

        ArrayList<HashMap<String, String>> List_nea = new ArrayList<HashMap<String, String>>(messages.size());


        for (Message msg : messages){

            des.add(msg.getDescription());// keimeno
            text.add(msg.getTitle());// titlos
            url.add(msg.getLink());// link
            imgl.add(msg.getImgLink());

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("name", msg.getTitle());
        map.put("date", msg.getDate());     


        List_nea.add(map);
        ListAdapter mSchedule = new SimpleAdapter(this, List_nea, R.layout.row,
                new String[] {"name", "date"}, new int[] {R.id.TextView01, R.id.TextView02});
        this.setListAdapter(mSchedule);
        }

    AnimationSet set = new AnimationSet(true);

    Animation animation = new AlphaAnimation(0.0f, 1.0f);
    animation.setDuration(400);
    set.addAnimation(animation);

    animation = new TranslateAnimation(
        Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
        Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f
    );

    animation.setDuration(400);
    set.addAnimation(animation);
    LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
    ListView listViewn = getListView();        
    listViewn.setLayoutAnimation(controller);

    }



    protected void onListItemClick(ListView l, View v, final int position, long id) {



        super.onListItemClick(l, v, position, id);
        Dialog dialog = new Dialog(this);
       String description = des.get(position).toString().replaceAll("\\<.*?>","");
       String imagee=imgl.get(position).toString();
        final URL link = url.get(position);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
            dialog.setContentView(R.layout.single);
            dialog.setCancelable(true);
            Toast msg = Toast.makeText(nea.this, "The url is  :  "+imagee, Toast.LENGTH_LONG);
            msg.show();
//xrisimopoiisa toast gia na elegxw poio link pernw apo to site



            TextView title_dialog = (TextView) dialog.findViewById(R.id.title_dialog);
            title_dialog.setText(text.get(position));


            TextView text = (TextView) dialog.findViewById(R.id.descr);
            text.setText(description);


            ImageView image1 = (ImageView) dialog.findViewById(R.id.image1);


            try {
                //where imageUrl is what you pulled out from the rss feed
                Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imagee).getContent());
                image1.setImageBitmap(bitmap); 
              } catch (MalformedURLException e) {
               //log exception here
              } catch (IOException e) {
                //log exception here
              }      
            Button btnt = (Button) dialog.findViewById(R.id.btnrss);//ti kanei to koumpi otan to patas gia to link
            btnt.setOnClickListener(new View.OnClickListener() {
                public void onClick (View view) {

                    Intent viewMessage = new Intent(Intent.ACTION_VIEW, Uri.parse(link.toExternalForm()));
                    startActivityForResult(viewMessage, 0);

                }  

            });           

            dialog.show();
    }

        //options menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu2) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu2, menu2);
        return true;
    }  

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.refresh:
            new BackgroundAsyncTask_nea().execute();
            break;


        }
        return true;
    }

    public class BackgroundAsyncTask_nea extends
       AsyncTask<Void, Void, Void> {
          private ProgressDialog dialog;
        int myProgress;   

        @Override
        protected void onPostExecute(Void result) {

            displayRss();
             dialog.dismiss();

        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
              dialog = ProgressDialog.show(nea.this, "", "Loading. Please wait...", true);
            myProgress = 0;
        }

        protected void onProgressUpdate(Integer... progress) {
          // TODO Auto-generated method stub
          //super.onProgressUpdate(values);

            dialog.setProgress(progress[0]);
         }

        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub

            loadFeed(this);
            return null;
        }



    }


    public final boolean isInternetOn() {
        ConnectivityManager connec =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        // ARE WE CONNECTED TO THE NET
        if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED ||
        connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTING ||
        connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTING ||
        connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED ) {
        // MESSAGE TO SCREEN FOR TESTING (IF REQ)
        //Toast.makeText(this, connectionType + ” connected”, Toast.LENGTH_SHORT).show();
        return true;
        } else if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED  ) {
        //System.out.println(“Not Connected”);
        return false;
        }
        return false;
        }
}

Why am i getting this error?How can i solve it?Thanks :)

EDIT:

Public void toast_doInBck(View view) {
        // Do something long
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 10; i++) {
                    Toast.makeText(nea.this,R.string.no_connection, Toast.LENGTH_SHORT).show();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                        }
                    });
                }
            }
        };
        new Thread(runnable).start();
    }

EDIT2:

    private void loadFeed(AsyncTask<Void, Void, Void> asyncTask){
        try{ 
            BaseFeedParser parser = new BaseFeedParser();
            messages = parser.parse();

            }
         catch (Throwable t){
              Log.e("OSFP.News",t.getMessage(),t);
Looper.prepare();
                Toast.makeText(nea.this, "Παρακαλώ προσπαθήστε αργότερα..",
                        Toast.LENGTH_SHORT).show();
                finish();
                Looper.loop();

            }
    }
user1156210
  • 141
  • 1
  • 1
  • 6
  • Did you read the message? `Can't create handler inside thread that has not called Looper.prepare()` – SLaks Jan 20 '12 at 18:41
  • Yes,i read it but i dont know how to solve it!Just call Looper.prepare before my toast,and then Looper.Loop after it? – user1156210 Jan 20 '12 at 18:42

4 Answers4

29

This is probably because you're trying to display something on doInBackground(). doInBackground runs in a worker thread which cannot do any UI work (including showing Toasts, which is what you're doing). Instead, all UI work should be done on onPostExecute().

Bruno Oliveira
  • 5,056
  • 18
  • 24
  • thanks for your answer!The UI is done on onPostExecute!I just throw a toast in the doInBackground if there is a problem with my connection.Isn't that possible? – user1156210 Jan 20 '12 at 18:44
6

You can't do any GUI work on a background thread. Instead you should post a Runnable to a handler created in the GUI thread to make your Toast execute on the correct thread.

EDIT: Since the homework tag was removed, I'll give an outline how to do it;

  • new() up a Handler in your GUI thread (onCreate is a good place) and save it in a member variable, say "handler".
  • Move showing your Toast to a Runnable (anonymous class is pretty good for this)
  • To show the toast, do a handler.post() with your Runnable as a parameter. The Runnable will execute in the GUI thread.

For a complete example, see this article.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • i m sorry but i need some more help.May i create something like my edit on the answer? – user1156210 Jan 20 '12 at 20:13
  • please,i have updated my answer (EDIT2)with a working solution i found..Could you please tell me if this way is correct? – user1156210 Jan 20 '12 at 20:36
  • You still cannot run loadFeed from a background thread, you need to put a handler.post() in the catch block, and give it a Runnable which calls your Toast methods in its run() method. – Joachim Isaksson Jan 20 '12 at 20:44
1

You're showing a Toast in loadFeed which is called in the doInBackground part of your AsyncTask. You shouldn't access the UI from there.

kabuko
  • 36,028
  • 10
  • 80
  • 93
1

I think In this code Toast make problem for you,

catch (Throwable t){
              Log.e("OSFP.News",t.getMessage(),t);

                Toast.makeText(nea.this, "Χρειάζεστε σύνδεση στο internet",
                        Toast.LENGTH_SHORT).show();
                finish();

            }

Because you are trying to do UI operation from worker thread of AsyncTask this will never allowed..

UPDATE: If you want to update something from the doInBackGround() of AsyncTask use publishProgress(Progress...) and onProgressUpdate(Progress...).

user370305
  • 108,599
  • 23
  • 164
  • 151