前段時間看到一個數據,據說中國網民數量已經達到7億多,看到這個數字就尿了,現在連小學生玩微信都啪啪啪的6,作爲移動應用開發者,你的APP要是沒有聯網功能的話那就太low了,當然要讓APP進行一些網絡請求也不是掃碼難事,今天咱就來一起加載一個網絡圖片玩玩。
首先你要準備一張用於加載的網絡圖片,取到它的網絡地址,當然爲了方便,我用Tomcat在本地搭建了一個web服務器,把它運行,圖片放到我web服務器的根目錄下。
服務器啓動以後,在我的瀏覽器訪問圖片。
OK,是可以訪問的,我的圖片就是放在上邊那個地址所對應的服務器位置裏,它就是一個網絡圖片,當然你可以從網上找你喜歡的圖片地址。
準備工作做好以後,下面就要在安卓應用中去請求網絡加載它了。
我在創建好安卓工程後,製作了下面這樣的佈局,很簡單,就是一個Button,下面還有一個ImageView。
接着就是在Activity裏聲明初始和化View控件了
private ImageView iv_downpic_main;
public void downPic (View v) {
<span style="white-space:pre"> </span>//圖片的網絡path路徑
<span style="white-space:pre"> String path = "http://192.168.0.109:8080/cool_man.jpg";</span>
<span style="white-space:pre"> </span>//聲明一個連接對象
<span style="white-space:pre"> HttpURLConnection conn = null;
//聲明一個輸入流</span>
<span style="white-space:pre"> InputStream is = null;
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>URL url = new URL(path);</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//打開url連接
<span style="white-space:pre"> </span>conn = (HttpURLConnection) url.openConnection();</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//設置請求方式爲GET
<span style="white-space:pre"> </span>conn.setRequestMethod("GET");</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//設置連接超時時間爲5秒
<span style="white-space:pre"> </span>conn.setConnectTimeout(5000);</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//設置讀取超時時間爲5秒
<span style="white-space:pre"> </span>conn.setReadTimeout(5000);</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//建立連接
<span style="white-space:pre"> </span>conn.connect();
<span style="white-space:pre"> //如果返回的請求碼爲200的話 </span>
<span style="white-space:pre"> </span>if(conn.getResponseCode() == 200){</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//得到一個連接輸入流
<span style="white-space:pre"> <span style="white-space:pre"> </span></span>is = conn.getInputStream();</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//用bitmap讀取輸入流
<span style="white-space:pre"> <span style="white-space:pre"> </span></span>bitmap = BitmapFactory.decodeStream(is);</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//設置圖片爲bitmap讀取到的圖片
<span style="white-space:pre"> <span style="white-space:pre"> </span></span>iv_downpic_main.setImageBitmap(bitmap);
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>} else {</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//請求碼不爲200的話,toast提示請求失敗
<span style="white-space:pre"> <span style="white-space:pre"> </span></span>Log.e("TAG", "請求失敗!");//
<span style="white-space:pre"> <span style="white-space:pre"> </span></span>Toast.makeText(MainActivity.this, "請求失敗!", 0).show();
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>} catch (Exception e) {
<span style="white-space:pre"> </span>// TODO Auto-generated catch block
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}finally{
<span style="white-space:pre"> </span>if(conn != null){</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//關閉連接
<span style="white-space:pre"> </span>conn.disconnect();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(is != null){
<span style="white-space:pre"> </span>try {</span>
<span style="white-space:pre"><span style="white-space:pre"> </span>//關閉輸入流
<span style="white-space:pre"> </span>is.close();
<span style="white-space:pre"> </span>} catch (IOException e) {
<span style="white-space:pre"> </span>// TODO Auto-generated catch block
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}</span>
</pre><pre name="code" class="java">
}
這樣的方法在安卓4.0之前是行的通的,然而在安卓4.0以後,這些代碼就不好使了,爲避免ANR的產生,程序在進行聯網等耗時操作時是禁止在主線程裏執行的。
改進的做法是,把聯網獲取圖片的操作拿到分線程去執行,然而跟新UI界面的操作用Handler在主線程進行UI跟新。
public class MainActivity extends Activity {
private static final int WHAT_DAWNLOAD_PICTURE = 0;
protected static final int WAHT_TOAST = 1;
private ImageView iv_downpic_main;
private Bitmap bitmap;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
iv_downpic_main.setImageBitmap(bitmap);
break;
case 1 :
Toast.makeText(MainActivity.this, "請求失敗!", 0).show();
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_downpic_main = (ImageView) findViewById(R.id.iv_downpic_main);
}
public void downPic (View v) {
final String path = "http://192.168.0.109:8080/cool_man.jpg";
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection conn = null;
InputStream is = null;
try {
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
if(conn.getResponseCode() == 200){
is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
handler.sendEmptyMessage(WHAT_DAWNLOAD_PICTURE);
} else {
Log.e("TAG", "請求失敗!");//
handler.sendEmptyMessage(WAHT_TOAST);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(conn != null){
conn.disconnect();
}
if(is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}).start();
}
}
這裏要說的是,Toast提示信息也需要在主線程進行跟新,如果單獨把它放在分線程執行的話,是麼有效果的,而且後臺也會報錯:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
代碼寫好以後,就運行測試吧。
點擊按鈕把酷男顯示出來。
效果還不錯!