1. 程式人生 > >Android基礎-獲取網路上的圖片並顯示

Android基礎-獲取網路上的圖片並顯示

android手機和瀏覽器也是一樣的,也可以通過網路通訊獲取資料,如呼叫webservice,EJB等。下面就通過一個小例子從網路獲取一幅圖片並顯示在手機上,開發中將會使用到一個新的元件ImageView.
設計效果圖:
這裡寫圖片描述
1.在AndroidManifest.xml中新增一個網路許可權

<uses-permission android:name="android.permission.INTERNET"/>

2.這是佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools
="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" >
<ImageView android:id="@+id/ivImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight
="1" />
<EditText android:id="@+id/edt" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:text="http://pic.nipic.com/2007-11-08/2007118192311804_2.jpg" /> <Button android:id="@+id/btnView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:onClick="viewImage" android:text="瀏覽" /> </LinearLayout>

預設圖片路徑
4.MainAvtivity.java中實現獲取網路圖片方法,利用button點選事件。

public class MainActivity extends Activity {
    Button button;
    ImageView imageView;
    EditText ed;
    private static final int MSG_SUCCESS = 0;// 獲取圖片成功的標識
    private static final int MSG_FAILURE = 1;// 獲取圖片失敗的標識

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

    public void findId() {
        button = (Button) findViewById(R.id.btnView);
        imageView = (ImageView) findViewById(R.id.ivImage);
        ed = (EditText) findViewById(R.id.edt);
    }

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

    private Handler handler = new Handler(){
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_SUCCESS:
                Bitmap bit = (Bitmap) msg.obj;
                imageView.setImageBitmap(bit);
                break;
            default:
                break;
            }
        };

    };

    public void viewImage(View view) {

        final String path = ed.getText().toString();//獲取輸入的圖片路徑
        if (TextUtils.isEmpty(path)) {
            Toast.makeText(MainActivity.this, " 路徑不為空", Toast.LENGTH_SHORT)
                    .show();
        } else {
            new Thread() {
                public void run() {
                    URL url;
                    try {
                        url = new URL(path);//發出請求
                        HttpURLConnection connection = (HttpURLConnection) url
                                .openConnection();
                        connection.setRequestMethod("GET");//設定請求方式這裡的方式必須為大寫
                        connection.setConnectTimeout(5000);//設定超時的時間
                        int code = connection.getResponseCode();//獲得狀態碼
                        if (code == 200) {
                            InputStream is = connection.getInputStream();
                            Bitmap bitmap = BitmapFactory.decodeStream(is);//寫入一個bitmap流
                            Message m = new Message();
                            m.what = MSG_SUCCESS;
                            m.obj = bitmap;
                            handler.sendMessage(m);
                        } else {
                            Toast.makeText(MainActivity.this, "開啟失敗",
                                    Toast.LENGTH_SHORT).show();
                        }

                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
}};}.start();
}}}

利用在主執行緒中新增一個執行緒來獲取圖片。主要就是為了避免ANR(Application Not Responding):應用程式無響應,如果應用程式不能響應使用者輸入
的話,系統會顯示ANR。主執行緒也是UI執行緒本身就幹了很多事情,繪製介面響應事件等。如果裡面再直接放入一些耗時的操作,如連線網路進行IO操作,就會阻塞主執行緒,帶來較差的使用者體驗。其中一個執行緒出現異常不會影響到其他執行緒更不會阻塞主執行緒(UI執行緒) ,這是多執行緒帶來的好處之一。

本次實驗主要是利用Handler.sendMessage(…)把訊息壓進訊息佇列,過後通過Handler.handleMessage(…)在UI執行緒中處理壓入的訊息。從佇列中取出訊息時會根據壓入的不同訊息來更新UI。圖片在外部執行緒中載入,載入完後sendmessage在主執行緒中更新UI。外部執行緒只顧載入圖片,而更新UI是主執行緒(UI執行緒)的事,這個就達到了多執行緒非同步載入網路圖片的目的。