简体   繁体   中英

android thread crashes application when there's no internet connection

heres my logcat error strace

06-17 10:50:59.578: E/AndroidRuntime(1899): FATAL EXCEPTION: AsyncTask #1
06-17 10:50:59.578: E/AndroidRuntime(1899): java.lang.RuntimeException: An error occured while executing doInBackground()
06-17 10:50:59.578: E/AndroidRuntime(1899):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.lang.Thread.run(Thread.java:856)
06-17 10:50:59.578: E/AndroidRuntime(1899): Caused by: java.lang.NullPointerException
06-17 10:50:59.578: E/AndroidRuntime(1899):     at com.merimasjid.prayertimes.hijri.FavouritePagePrayerTimes1$LoadTimes.doInBackground(FavouritePagePrayerTimes1.java:561)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at com.merimasjid.prayertimes.hijri.FavouritePagePrayerTimes1$LoadTimes.doInBackground(FavouritePagePrayerTimes1.java:1)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-17 10:50:59.578: E/AndroidRuntime(1899):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
06-17 10:50:59.578: E/AndroidRuntime(1899):     ... 4 more

I have a single thread which is automatically executed when the app is launched and this thread is defined inside fragment . The thread grabs some JSON data from the internet and diplays it on the screen and the app works fine when the data connection or wifi is on but in absence of packet data it just crashes the app when launched

class LoadTimes extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //pBar.setVisibility(View.VISIBLE);
    }


    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
    //  params.add(new BasicNameValuePair("areaID","0"));

        try{
        params.add(new BasicNameValuePair("MasjidID",String.valueOf(_appPrefs.getFavOneID())));
        params.add(new BasicNameValuePair("Date", getParameterisedDate()));
        //params.add(new BasicNameValuePair("date",getParameterisedDate()));
        }catch(Exception e){}
        JSONObject json = null;
        try{
        json = jsonParser.makeHttpRequest(URL_GET_TIMES, "GET",
                params);
        }catch(Exception e){}

        // Check your log cat for JSON response
        Log.d("Outbox JSON: ", json.toString());
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");

        try {

            albums = json.getJSONArray("masjids");
            // looping through All messages

            if(albums!=null){
            for (int i = 0; i < albums.length(); i++) {
                JSONObject c = albums.getJSONObject(i);

                        Date d1 = df.parse(c.getString("FajarAzan"));
                        SunrH = d1.getHours();
                        SunRM = d1.getMinutes();

                        Date d2 = df.parse(c.getString("FajarAzan"));
                        fajrH = d2.getHours();
                        fajrM = d2.getMinutes();

                        Date d3 = df.parse(c.getString("ZoharAzan"));
                        DhuhrH = d3.getHours();
                        DhuhrM = d3.getMinutes();

                        Date d4 = df.parse(c.getString("AsarAzan"));
                        AsrH = d4.getHours();
                        AsrM = d4.getMinutes();

                        Date d5 = df.parse(c.getString("Maghrib"));
                        MaghribH = d5.getHours();
                        MaghribM = d5.getMinutes();


                        Date d6 = df.parse(c.getString("IshaAzan"));
                        IshaH = d6.getHours();
                        IshaM = d6.getMinutes();


                        _appPrefs.storeFavouriteMasjidTimes(fajrH, fajrM, SunrH, SunRM, DhuhrH, DhuhrM, AsrH, AsrM, MaghribH, MaghribM, IshaH, IshaM, day, month, year, _appPrefs.getFavOneID());
                    try{
                        initNamazTimes();
                    }catch(Exception e){}
                    /*
                        namazTimesH = new int[]{fajrH,SunrH,DhuhrH,AsrH,MaghribH,IshaH};
                        namazTimesM = new int[]{fajrM,SunRM,DhuhrM,AsrM,MaghribM,IshaM};*/

            }
            }
        } catch (Exception e) {
        //  pBar.setVisibility(View.GONE);
        //  
        //  cantGet = true;
            publishProgress(null);
            Log.e("Exception while Loading Times",e.toString());
        }

        return null;
    }

    @Override
    public  void onProgressUpdate(String... args) {
        super.onProgressUpdate(args);
        try{
        FetchStoreFavouriteNamazTimings.cantGetNamazTimes();}catch(Exception e){}

    }
    protected void onPostExecute(String file_url) {
    if(cantGet)
        {
            FetchStoreFavouriteNamazTimings.cantGet = false;
        }
        else{   
            try{
            generateButtonsAlarms();
            generateButtonsFavourites();}
            catch(Exception e){}
            /////////////////////////////////////////////////////////////////////
        }
    }

}
JSONObject json = null; 

try{
   json = jsonParser.makeHttpRequest(URL_GET_TIMES, "GET", params);
}catch(Exception e){
   // handle me!
}

You said there is no internet connection, so probably an exception is raised that you have not handled. Later you access the json object that is definately null .

UPDATE:

Most of the other answers suggest to check internet connection before executing the AsyncTask. But that is not a complete solution, since the connection could be lost after the "checking" and before the network call, that would lead to the same exception.

You must handle exceptions! Checking internet connection does not solve the problem.

Create a one more class ConnectionDetector

public class ConnectionDetector {

    private Context _context;

    public ConnectionDetector(Context context){
        this._context = context;
    }

    public boolean isConnectingToInternet(){
        ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
          if (connectivity != null) 
          {
              NetworkInfo[] info = connectivity.getAllNetworkInfo();
              if (info != null) 
                  for (int i = 0; i < info.length; i++) 
                      if (info[i].getState() == NetworkInfo.State.CONNECTED)
                      {
                          return true;
                      }

          }
          return false;
    }
}

Then from your activity first declare

ConnectionDetector cd = new ConnectionDetector(getApplicationContext());

Before calling AsyncTask check internet connection

Boolean isInternetPresent = cd.isConnectingToInternet(); // true or false

    if (isInternetPresent)
    {
       // call your AsyncTask
    }

    else

    // display a toast message saying "No internet connection"

Also don't forget to catch the exception . Sometime internet breaks down while getting information. So better to catch the exception.

Please check internet connection before calling .execute() method of your class.

Try this method and call this function in if condition, if its return true then call your Asyncktask class otherwise show some alert message.

public boolean isConnectingToInternet(){
        ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
          if (connectivity != null) 
          {
              NetworkInfo[] info = connectivity.getAllNetworkInfo();
              if (info != null) 
                  for (int i = 0; i < info.length; i++) 
                      if (info[i].getState() == NetworkInfo.State.CONNECTED)
                      {
                          return true;
                      }

          }
          return false;
    }

You could verify if the phone has a connection to the wifi

public static Boolean isWifiAvailable(Context context)
    {
        ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        return networkInfo.isConnected();
    }

Don't forget to add the proper permision in the manifest:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM