2016-01-20 51 views
2

我正在开发执行异步任务的新闻应用程序,但在异步任务运行期间,如果互联网连接丢失,应用程序崩溃。我试图通过使用广播接收器解决问题,并在连接丢失时取消异步任务,但问题仍然存在。以下是我的完整活动源代码。取消AsyncTask在运行过程中互联网连接丢失时

public class News extends AppCompatActivity{ 

    // Declare Variables 
    JSONObject jsonobject; 
    JSONArray jsonarray; 
    GridView gridview; 
    GridViewAdapter adapter; 
    ProgressDialog mProgressDialog; 
    ArrayList<HashMap<String, String>> arraylist; 

    Toolbar mToolbar; 

    static String NEWS = "news"; 
    static String ID = "id"; 
    static String PROFILE_PIC = "news_pic"; 


    DownloadNews downloader; 

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

     IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);   
     registerReceiver(networkStateReceiver, filter); 


     mToolbar = (Toolbar) findViewById(R.id.toolbar); 

     setSupportActionBar(mToolbar); 
     getSupportActionBar().setDisplayShowHomeEnabled(true); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

     gridview = (GridView) findViewById(R.id.discoverGrid); 

     downloader = new DownloadNews(); 



     ConnectionDetector cd = new ConnectionDetector(getApplicationContext()); 
     if (!cd.isConnectingToInternet()) { 

      Toast.makeText(getApplicationContext(),"Couldn't refresh",Toast.LENGTH_SHORT).show(); 


      } 
     else 
     { 

      downloader.execute(); 
      Handler handler = new Handler(); 
      handler.postDelayed(new Runnable() 
      { 
       @Override 
       public void run() { 
        if (downloader.getStatus() == AsyncTask.Status.RUNNING){ 
         downloader.cancel(true); 
        linlaHeaderProgress.setVisibility(View.GONE); 
        Toast.makeText(getApplicationContext(),"Internet Connection is Down",Toast.LENGTH_SHORT).show(); 

       } 
        else if(downloader.getStatus() == AsyncTask.Status.FINISHED){ 
        linlaHeaderProgress.setVisibility(View.GONE); 

        } 

       } 
      }, 15000); 
     } 

    } 

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

     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     int id = item.getItemId(); 
     if (id == R.id.action_search) { 
      return true; 
     } 


     else if (id == android.R.id.home) { 
      onBackPressed(); 
      finish(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private class DownloadNews extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      mProgressDialog.show(); 

     } 

     @Override 
     protected Void doInBackground(Void... params) { 

      while(true){ 

        if (isCancelled()) 
        break; 
      } 

      arraylist = new ArrayList<HashMap<String, String>>(); 
      // Retrieve JSON Objects from the given URL address 
      try { 
       try { 
        jsonobject = JSONfunctions 
          .getJSONfromURL("http://www.example.com/app/news.php"); 
       } catch (UnknownHostException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } catch (ConnectTimeoutException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } catch (SocketTimeoutException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 


      try { 
       // Locate the array name in JSON 
       jsonarray = jsonobject.getJSONArray("news"); 

       for (int i = 0; i < jsonarray.length(); i++) { 

        HashMap<String, String> map = new HashMap<String, String>(); 
        jsonobject = jsonarray.getJSONObject(i); 
        // Retrieve JSON Objects 
        map.put("id", jsonobject.getString("id")); 
        map.put("profile_pic", jsonobject.getString("news_pic")); 
        // Set the JSON Objects into the array 
        arraylist.add(map); 
       } 

      } catch (JSONException e) { 
       Log.e("Error", e.getMessage()); 
       e.printStackTrace(); 
      } 




      return null; 
     } 

     @Override 
     protected void onPostExecute(Void args) { 
      adapter = new GridViewAdapter(News.this, arraylist); 
      gridview.setAdapter(adapter); 
      mProgressDialog.dismiss(); 

     } 

     @Override 
     protected void onCancelled(){ 
      downloader.cancel(true); 

     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      finish(); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    BroadcastReceiver networkStateReceiver = new BroadcastReceiver() { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 

      if(!noConnectivity) { 
        onConnectionFound(); 
      } else { 
        onConnectionLost(); 
      } 
     } 
    }; 


    public void onConnectionLost() { 
     Toast.makeText(this, "Connection lost", Toast.LENGTH_LONG).show(); 
     downloader.cancel(true); 

    } 

    public void onConnectionFound() { 
     Toast.makeText(this, "Connection found", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unregisterReceiver(networkStateReceiver); 
    } 

} 

回答

0

您的代码已损坏。你的while(true)循环被误写,循环直到你被取消,然后试图做网络请求。这可能不是你想要的。你想要做的只是完全删除该循环(之后可能需要进一步的调试)。如果你真的想不断地下载数据,你需要一个线程而不是一个AsyncTask,并且你的函数的主体都应该在while循环中。

+0

我会尝试更新代码 –