2

I'm developing my android app for a conference. In, my login page I printed an error message when no internet connection. but, the app crashes when no internet connection and following error message display in logcat. I followed many questions from stack overflow and may be I can't understand, I couldn't find my answer.

08-19 10:01:21.840  

8931-9124/com.NICT.nict E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-691

java.lang.RuntimeException: Can't create handler inside thread that hasnot called Looper.prepare()

           at android.os.Handler.<init>(Handler.java:205)

           at android.os.Handler.<init>(Handler.java:119)

           atandroid.widget.Toast$TN.<init>(Toast.java:325)

           atandroid.widget.Toast.<init>(Toast.java:91)

           atandroid.widget.Toast.makeText(Toast.java:239)

           at com.NICT.nict.services.MessageHandler.showMessage(MessageHandler.java:9)
           at com.NICT.nict.LoginActivity$1$1.run(LoginActivity.java:117)

           at java.lang.Thread.run(Thread.java:838)

Here is my login activity

package com.NICT.nict;

import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;

import com.NICT.nict.WorkShopActivity.HttpAsyncTask;
import com.NICT.nict.services.EmailValidator;
import com.NICT.nict.services.MessageHandler;
import com.NICT.nict.services.ServiceHandler;

public class LoginActivity extends Activity {

 public final static String URL = "http://demo.et.lk/nitcapi/api/login";

 public static String Uid;

 private Button loginBtn;

 private EditText codeEdit;

 private EditText nameEdit;

 private EditText emailEdit;

 private ServiceHandler sh = new ServiceHandler();

 private boolean errorStatus;
 
 private ProgressBar spinner;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_login);

  loginBtn = (Button) findViewById(R.id.loginBtn);
  codeEdit = (EditText) findViewById(R.id.codeEdit);
  nameEdit = (EditText) findViewById(R.id.nameEdit);
  emailEdit = (EditText) findViewById(R.id.emailEdit);
  spinner = (ProgressBar) findViewById(R.id.progressBar1);
  spinner.setVisibility(View.GONE);
  loginBtn.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {

    if (!ServiceHandler.isOnline(getApplicationContext())) {
     MessageHandler.showMessage("You are not online.",
       getApplicationContext());
    }
    new Thread(new Runnable() {
     public void run() {

      String code = codeEdit.getText().toString();
      String email = emailEdit.getText().toString();
      String name = nameEdit.getText().toString();
      if (code.length() == 0) {
       runOnUiThread(new Runnable() {
        public void run() {
         MessageHandler.showMessage(
           "Please Enter the app code",
           getApplicationContext());
         errorStatus = true;
        }
       });
       ;
      } else if (name.length() == 0) {
       runOnUiThread(new Runnable() {
        public void run() {
         MessageHandler.showMessage(
           "Please Enter Your Name",
           getApplicationContext());
         errorStatus = true;
        }
       });
       ;
      } else if (email.length() == 0) {
       runOnUiThread(new Runnable() {
        public void run() {
         MessageHandler.showMessage(
           "Please Enter Your Email",
           getApplicationContext());
         errorStatus = true;
        }
       });
       ;
      }
      
      EmailValidator emailValidator = new EmailValidator();
      if(!emailValidator.validate(email)){
       runOnUiThread(new Runnable() {
        public void run() {
         MessageHandler.showMessage(
           "Invalid Email",
           getApplicationContext());
         errorStatus = true;
        }
       });
       ;
      }

      String jsonStr = null;
      if (!errorStatus) {
       
       if (!ServiceHandler.isOnline(getApplicationContext())) {
        MessageHandler.showMessage("You are not online.",
          getApplicationContext());
       } else {
        ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        

             // notify user you are online
         try{
           runOnUiThread(new Runnable() {
            public void run() {
          spinner.setVisibility(View.VISIBLE);
            }
           });
           ;
          
         jsonStr = sh.makeServiceCall(URL + "/" + code + "/"
           + name + "/" + email, ServiceHandler.GET);
         System.out.println(URL + "/" + code + "/" + name + "/"
           + email);
         
         }
         catch (Exception e){
          spinner.setVisibility(View.GONE);
          runOnUiThread(new Runnable() {
           public void run() {
          MessageHandler.showMessage("You are not online.",
            getApplicationContext());
          
           }
          });
          ;
          
          
         }

        
       }

       if (jsonStr != null) {
        String status = "";
        String msg = "";

        try {
         JSONObject jsonObj = new JSONObject(jsonStr);
          runOnUiThread(new Runnable() {
           public void run() {
         spinner.setVisibility(View.GONE);
           }
          });
          ;
         
         if (jsonObj != null
           && jsonObj.has("status")) {
          status = jsonObj.getString("status");
          msg = jsonObj.getString("message");
          if(jsonObj.has("uid"))
           Uid = jsonObj.getString("uid");
          System.out.println(jsonObj);
          if (status.equals("OK")) {
           Intent myIntent = new Intent(
             getBaseContext(),
             MainMenuActivity.class);
           startActivityForResult(myIntent, 0);
          } else if (status.equals("ERROR")) {
           final String errorMsg = msg;
           runOnUiThread(new Runnable() {
            public void run() {
             MessageHandler
               .showMessage(
                 errorMsg,
                 getApplicationContext());
            }
           });
           ;
          } else {
           runOnUiThread(new Runnable() {
            public void run() {
             MessageHandler
               .showMessage(
                 "Oops..! something wrong with the service. Please try again Later.",
                 getApplicationContext());
            }
           });
           ;
          }
         }
        } catch (Exception e) {
         System.out
           .println("Creation of json object failed");
        }

       }
      }

     }
    }).start();

   }
  });
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.login, menu);
  return true;
 }

}

Here is my serviceHandler.

package com.NICT.nict.services;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

public class ServiceHandler {

 static String response = null;
 public final static int GET = 1;
 public final static int POST = 2;

 public ServiceHandler() {

 }

 /**
  * Making service call
  * 
  * @url - url to make request
  * @method - http request method
  * */
 public String makeServiceCall(String url, int method) {
  return this.makeServiceCall(url, method, null);
 }

 /**
  * Making service call
  * 
  * @url - url to make request
  * @method - http request method
  * @params - http request params
  * */
 public String makeServiceCall(String url, int method,
   List<NameValuePair> params) {
  try {
   // http client
   DefaultHttpClient httpClient = new DefaultHttpClient();
   HttpEntity httpEntity = null;
   HttpResponse httpResponse = null;

   // Checking http request method type
   if (method == POST) {
    HttpPost httpPost = new HttpPost(url);
    // adding post params
    if (params != null) {
     httpPost.setEntity(new UrlEncodedFormEntity(params));
    }

    httpResponse = httpClient.execute(httpPost);

   } else if (method == GET) {
    // appending params to url
    if (params != null) {
     String paramString = URLEncodedUtils
       .format(params, "utf-8");
     url += "?" + paramString;
    }
    HttpGet httpGet = new HttpGet(url);

    httpResponse = httpClient.execute(httpGet);

   }
   httpEntity = httpResponse.getEntity();
   response = EntityUtils.toString(httpEntity);

  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }

  return response;

 }

 public static boolean isOnline(Context ctx) {
  ConnectivityManager cm;
  NetworkInfo info = null;
  try {
   cm = (ConnectivityManager) ctx
     .getSystemService(Context.CONNECTIVITY_SERVICE);
   info = cm.getActiveNetworkInfo();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return (info!=null&&!info.equals(null));
 }
}
  • 1
    possible duplicate of [Can't create handler inside thread that has not called Looper.prepare()](http://stackoverflow.com/questions/3875184/cant-create-handler-inside-thread-that-has-not-called-looper-prepare) – King of Masses Aug 19 '15 at 05:20
  • @Manuil I think you are showing a `Toast` somewhere in a `non UI` thread.. – Emil Aug 19 '15 at 05:22
  • Found the anzwer. Thanx for ur comments and answers :) –  Aug 19 '15 at 05:51

3 Answers3

1

add this following snippet in your if condition::

 if (!ServiceHandler.isOnline(getApplicationContext())) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(
    new Runnable()
    {
        @Override
        public void run()
        {
            MessageHandler.showMessage("You are not online.",
                        getApplicationContext());
        }
    }
);
}
King of Masses
  • 18,405
  • 4
  • 60
  • 77
techroid
  • 477
  • 4
  • 11
0

Try this.when you see runtimeException due to Looper not prepared before handler.

Handler handler = new Handler(Looper.getMainLooper());

From Android Docs:

LOOPER

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

Looper.getMainLooper()

Returns the application's main looper, which lives in the main thread of the application.

I hope it helps!

Rajesh Jadav
  • 12,801
  • 5
  • 53
  • 78
0

Android basically works on two thread types namely UI thread and background thread.

Try this,

activity.runOnUiThread(new Runnable() {
 public void run() {
  //run your code here.....
 }
});
Ranjit Bisht
  • 157
  • 10