2013-02-08 26 views
0

我對Android比較陌生,我試圖按照this教程。Android數據下載實驗

我已經創建了下面的代碼一個小項目:

package com.example.revivaltimesv1; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.io.UnsupportedEncodingException; 
import java.net.HttpURLConnection; 
import java.net.URL; 

import android.app.Activity; 
import android.content.Context; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.widget.TextView; 
import android.widget.Toast; 

public class MainActivity extends Activity { 

    private static final int LENGTH_LONG = 10; 
    private TextView message;// = (TextView)findViewById(R.id.message); 

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

     message = (TextView)findViewById(R.id.message); 

     Log.i("mine", "TESTING ... TESTING!!!"); 

     ConnectivityManager conManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo networkInfo = conManager.getActiveNetworkInfo(); 
     if(networkInfo != null && networkInfo.isConnected()){ 
      Toast.makeText(this, "Established Network Connection!", LENGTH_LONG).show(); 
      String stringURL = "http://178.79.128.76/GTK/node/7"; 
      new DownloadStuff().execute(stringURL); 
//   new test().execute(); 
      //message.setText("WORKING"); 
     }else{ 
      Toast.makeText(this, "No Network Connection!", LENGTH_LONG).show(); 
     } 
    } 

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

//} 

/* private class test extends AsyncTask<String, String, String>{ 
     @Override 
     protected String doInBackground(String... params) { 
      // TODO Auto-generated method stub 
      return null; 
     } 
    } 
*/ 
    private class DownloadStuff extends AsyncTask<String, String, String>{ 

     protected String doInBackground(String... url) { 
      // TODO Auto-generated method stub 
      Log.i("CHECK", "OUTSIDE"); 
      try{ 
       Log.i("CHECK", "SUCCESS: " + url[0]); 
       downloadUrl(url[0]); 
       Toast.makeText(getApplicationContext(), "WORKING !!!", LENGTH_LONG).show(); 
      }catch(IOException i){ 
       Log.i("CHECK", "NOT so successful"); 
       Toast.makeText(getApplicationContext(), "ERROR: unable to establish contact with URL", LENGTH_LONG).show();  
      } 
      return null; 
     } 

     protected void onPostExecute(String result) { 
      // TODO Auto-generated method stub 
//   super.onPostExecute(result); 
      message.setText("Hurray!"); 
     } 

     // Given a URL, establishes an HttpUrlConnection and retrieves 
     // the web page content as a InputStream, which it returns as 
     // a string. 
     private String downloadUrl(String myurl) throws IOException { 
      InputStream is = null; 
      // Only display the first 500 characters of the retrieved 
      // web page content. 
      int len = 500; 

      try { 
       URL url = new URL(myurl); 
       HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
       conn.setReadTimeout(10000 /* milliseconds */); 
       conn.setConnectTimeout(15000 /* milliseconds */); 
       conn.setRequestMethod("GET"); 
       conn.setDoInput(true); 
       // Starts the query 
       conn.connect(); 
       int response = conn.getResponseCode(); 
       Log.d("DEBUG_TAG", "The response is: " + response); 
       is = conn.getInputStream(); 

       // Convert the InputStream into a string 
       String contentAsString = readIt(is, len); 
       return contentAsString; 

      // Makes sure that the InputStream is closed after the app is 
      // finished using it. 
      } finally { 
       if (is != null) { 
        is.close(); 
       } 
      } 
     } 
     public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException { 
      Reader reader = null; 
      reader = new InputStreamReader(stream, "UTF-8");   
      char[] buffer = new char[len]; 
      reader.read(buffer); 
      return new String(buffer); 
     } 
    } 

} 

該應用程序的工作原理簡單,但隨後崩潰給我下面的反饋:

02-08 03:39:16.316: E/AndroidRuntime(5106): FATAL EXCEPTION: AsyncTask #1 
02-08 03:39:16.316: E/AndroidRuntime(5106): java.lang.RuntimeException: An error occured while executing doInBackground() 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.lang.Thread.run(Thread.java:1102) 
02-08 03:39:16.316: E/AndroidRuntime(5106): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at android.os.Handler.<init>(Handler.java:121) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at android.widget.Toast.<init>(Toast.java:68) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at android.widget.Toast.makeText(Toast.java:231) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at com.example.revivaltimesv1.MainActivity$DownloadStuff.doInBackground(MainActivity.java:74) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at com.example.revivaltimesv1.MainActivity$DownloadStuff.doInBackground(MainActivity.java:1) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
02-08 03:39:16.316: E/AndroidRuntime(5106):  ... 4 more 

我看遍至的底部錯誤堆棧,但... 4更多似乎隱藏與我的代碼相關的部分 - 我認爲。

回答

1

實際上是在logcat的堆棧跟蹤清楚地顯示的錯誤:02-08 03:39:16.316: E/AndroidRuntime(5106): at com.example.revivaltimesv1.MainActivity$DownloadStuff.doInBackground(MainActivity.java:74)

任何Toasts/UI功能,最好應在onPostExecute()來完成。但是,如果您必須在doInBackground()中執行此操作,請將其置於Runnable中,如代碼所示。

Runnable run = new Runnable() { 

    @Override 
    public void run() { 
     Toast.makeText(getApplicationContext(), "WORKING !!!", LENGTH_LONG).show(); 

    } 
}; MainActivity.this.runOnUiThread(run); 

瞭解更多關於AsyncTasks here,特別是標題爲4個步驟

0

不要在後臺線程中顯示Toast

private class DownloadStuff extends AsyncTask<String, String, String>{ 

     protected String doInBackground(String... url) { 
      // TODO Auto-generated method stub 
      Log.i("CHECK", "OUTSIDE"); 
      try{ 
       // .... 
       Toast.makeText(getApplicationContext(), "WORKING !!!", LENGTH_LONG).show(); 
      }catch(IOException i){ 

       Toast.makeText(getApplicationContext(), "ERROR: unable to establish contact with URL", LENGTH_LONG).show();  
      } 
      return null; 
} 
1

你不能在非UI線程顯示吐司。

您可以將消息發佈到UI線程,並讓UI線程處理該消息。

1

您不能使用來自非UI線程的Toast。您可以從onPostExecute()中顯示一個Toast,因爲它是從UI線程調用的,但不是從doInBackground()調用的,因爲它在自己的線程中運行。

0

當您使用異步任務時,請確保它不在主線程上工作,因此無法顯示Toast

AsyncTask類有五種方法如

  • onPreExecute() - 此方法在UI線程上運行的後臺處理 開始之前。
  • doInBackground() - 此方法在後臺運行,並且是所有 實際工作完成的位置。
  • publishProgress() - 這種方法,從doInBackground() 方法調用,週期性地通知UI線程關於後臺進程 進度。此方法將信息發送到UI進程。
  • onProgressUpdate() - 只要 doInBackground()方法調用publishProgress(),此方法就在UI線程上運行。此方法從後臺進程收到 信息。
  • onPostExecute() - 一旦完成背景 處理,此方法在UI線程上運行。

因此,只要您要執行像顯示進程狀態的操作,您應該使用OnProcessUpdate()方法,因爲它允許您與主線程交互。