2012-11-19 101 views
0

可能重複:
Download a file with Android, and showing the progress in a ProgressDialog從網站崩潰負荷圖像

我試圖從網站加載圖像,我看到了這樣一個問題:Android load from URL to Bitmap但我的應用程序崩潰,在這條線: conn.connect();

public class HTTPTest extends Activity { 

ImageView imView; 
String imageUrl = "http://api.androidhive.info/images/sample.jpg"; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.main); 

    Button bt3 = (Button) findViewById(R.id.get_imagebt); 
    bt3.setOnClickListener(getImgListener); 
    imView = (ImageView) findViewById(R.id.imview); 
} 

View.OnClickListener getImgListener = new View.OnClickListener() { 

    @Override 
    public void onClick(View view) { 
     // TODO Auto-generated method stub 
     downloadFile(imageUrl); 
    } 
}; 

Bitmap bmImg; 

void downloadFile(String fileUrl) { 
    URL myFileUrl = null; 
    try { 
     myFileUrl = new URL(fileUrl); 
    } catch (MalformedURLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     HttpURLConnection conn = (HttpURLConnection) myFileUrl 
       .openConnection(); 
     conn.setDoInput(true); 
     conn.connect(); 
     InputStream is = conn.getInputStream(); 

     bmImg = BitmapFactory.decodeStream(is); 
     imView.setImageBitmap(bmImg); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

的main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
> 
<TextView 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:text="Hello World, HTTPImage load test" 
/> 
    <Button 
android:id="@+id/get_imagebt" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:text="Get an image" 
android:layout_gravity="center" 
/> 
<ImageView 
android:id="@+id/imview" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_gravity="center" 
/> 

我的清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.androidtest" 
android:versionCode="1" 
android:versionName="1.0" > 
<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="16" /> 


<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name="com.example.androidtest.HTTPTest" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

<uses-permission android:name="android.permission.INTERNET"></uses-permission> 
<!-- Permission to write to external storage --> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
</manifest> 

在此先感謝您的幫助!

Germain。

+0

我只能猜測,例外是NetworkOnMainThread ... – Sam

+0

哦的確是的。我該如何解決這個問題? 我的目錄下載: 11-19 15:12:52.655:E/AndroidRuntime(21823):致命異常:主 11-19 15:12:52.655:E/AndroidRuntime(21823):android.os.NetworkOnMainThreadException 11-19 15:12:52.655:E/AndroidRuntime(21823):\t at android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1178) .. – GermainGum

+0

將來總是將LogCat添加到您的問題中應用程序崩潰,這是幫助我們解決錯誤的路線圖。 – Sam

回答

2

,但在這行我的應用程序崩潰:conn.connect();

就Android 3+你不能執行主線程的可能速度較慢的網絡操作。

在AsyncTask中下載圖片,使其不會減慢用戶體驗。只需將您的downloadFile()方法轉換爲AsyncTask的doInBackground()方法即可。

如果你需要詳細的細節,有一個very extensive answer here


加成
使用吉博的doInBackground()你可能從試圖從不同的線程,你不能做訪問UI得到一個錯誤。你可以在你的AsyncTask重寫onPostExecute()你的意見的工作,因爲它可以訪問到UI線程:

@Override 
protected void onPostExecute(String unused) { 
    imView.setImageBitmap(bmImg); 
} 
+0

非常感謝您的幫助! – GermainGum

3

您應該運行在另一個線程上的所有網絡請求(即不是UI線程)。事實上,Android可以讓你做到這一點。否則,當你等待迴應時,你的用戶界面會被鎖定。改變你的downloadFile()方法看起來像這樣。一個AsyncTask將在另一個線程上運行你的代碼。執行任務需要一段時間的好習慣。

void downloadFile(String fileUrl) { 

    AsyncTask<String, Object, String> task = new AsyncTask<String, Object, String>() { 

     @Override 
     protected String doInBackground(String... params) { 
      URL myFileUrl = null; 
      try { 
       myFileUrl = new URL(params[0]); 
      } catch (MalformedURLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      try { 
       HttpURLConnection conn = (HttpURLConnection) myFileUrl 
         .openConnection(); 
       conn.setDoInput(true); 
       conn.connect(); 
       InputStream is = conn.getInputStream(); 

       bmImg = BitmapFactory.decodeStream(is); 
       imView.setImageBitmap(bmImg); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      return null; 
     } 
    }; 
    task.execute(fileUrl); 

} 
+0

您只能運行一次AsyncTask的實例。 「該任務只能執行一次(如果嘗試執行第二次執行,則會引發異常)。」http://developer.android.com/reference/android/os/AsyncTask.html – Jimbo

+0

我試過這個,但是我有這個錯誤: 11-19 15:43:52.620:E/AndroidRuntime(23369):致命異常:AsyncTask#1 11-19 15:43:52.620:E/AndroidRuntime(23369):java.lang.RuntimeException:An執行doInBackground()時發生錯誤 11-19 15:43:52.620:E/AndroidRuntime(23369):\t at android.os.AsyncTask $ 3.done(AsyncTask.java:278) 11-19 15:43:52.620 :E/AndroidRuntime(23369):\t at java.util.concurrent.FutureTask $ Sync.innerSetException(FutureTask.java:273)... – GermainGum

+0

你可以發佈完整的stacktrace嗎? – Jimbo