1. 程式人生 > >Android核心技術-day04-01-網路圖片檢視器(安卓訊息迴圈機制)

Android核心技術-day04-01-網路圖片檢視器(安卓訊息迴圈機制)

package com.gaozewen.netimageviewer;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final int LOAD_IMAGE = 1;
    private static final int LOAD_ERROR = 2;
    private ImageView iv;
    private List<String> paths;
    private int currentPosition = 0;
    // UIThread 主執行緒 ↓
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case LOAD_IMAGE:
                    Bitmap bitmap = (Bitmap) msg.obj;
                    iv.setImageBitmap(bitmap);
                    Toast.makeText(MainActivity.this,"載入圖片成功", Toast.LENGTH_SHORT).show();
                    break;
                case LOAD_ERROR:
                    Toast.makeText(MainActivity.this,"載入圖片失敗", Toast.LENGTH_SHORT).show();
                    break;
            }
            return true;
        }
    });

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

        iv = (ImageView) findViewById(R.id.iv);
        // 1.連結伺服器,獲取所有的圖片連結資訊
        loadAllImagePath();
    }

    // 獲取全部圖片資源路徑
    private void loadAllImagePath() {
        new Thread() {
            @Override
            public void run() {
                // 獲取伺服器資料
                try {
                    URL url = new URL("http://192.168.1.102:8080/img/gaga.html");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET"); // 注意 GET 請求必須大寫
                    int code = conn.getResponseCode();
                    if (code == 200) { // 返回成功
                        InputStream is = conn.getInputStream();
                        File file = new File(getCacheDir(), "info.txt");
                        FileOutputStream fos = new FileOutputStream(file);
                        byte[] buffer = new byte[1024];
                        int len = 0;
                        while ((len = is.read(buffer)) != -1) {
                            fos.write(buffer, 0, len);
                        }
                        fos.flush();
                        fos.close();
                        is.close();

                        beginLoadImage();
                    } else if (code == 404) {
                        Message msg = Message.obtain();
                        msg.what = LOAD_ERROR;
                        msg.obj = "獲取html失敗,返回碼:" + code;
                        mHandler.sendMessage(msg);
                    }else {
                        Message msg = Message.obtain();
                        msg.what = LOAD_ERROR;
                        msg.obj = "伺服器異常,返回碼:" + code;
                        mHandler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

    // 開始載入圖片,在從伺服器獲取完畢圖片資源路徑之後執行
    private void beginLoadImage() {
        try {
            paths = new ArrayList<>();
            File file = new File(getCacheDir(), "info.txt");
            FileInputStream fis = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            String line;
            while ((line = br.readLine()) != null) {
                paths.add(line);
            }
            br.close();
            fis.close();

            loadImageByPath(paths.get(currentPosition));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //
    private void loadImageByPath(final String path) {
        new Thread() {
            @Override
            public void run() {
                try {
                    File file = new File(getCacheDir(), path.replace("/", "") + ".jpg");
                    if (file.exists() && file.length() > 0){ // 快取中有檔案
                        System.out.println("通過快取把圖片獲取出來...");

                        Message msg = Message.obtain();
                        msg.what = LOAD_IMAGE;
                        msg.obj = BitmapFactory.decodeFile(file.getAbsolutePath());
                        mHandler.sendMessage(msg);

                        // 安卓訊息迴圈機制
//                        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
//                        iv.setImageBitmap(bitmap);
                        /**
                         * 建立子執行緒 訊息迴圈!!!!
                         */
                        // UIThread 被建立之後就自帶了一個 Looper,
                        // 這個 Looper 管理自身的 MessageQueue ,
                        // 其他創建出來的子執行緒 預設沒有 Looper,
                        // 只能呼叫 Looper.prepare 和 Looper.loop 方法來進行訊息迴圈
                        // 並且要 new 一個 Handler 物件來處理取出的 Message 物件
                        /*Looper.prepare();
                        mHandler = new Handler(){
                            @Override
                            public void handleMessage(Message msg) {
                                Toast.makeText(MainActivity.this,"載入圖片完成" + msg.what, Toast.LENGTH_SHORT).show();
                            }
                        };
                        Message msg = Message.obtain();
                        msg.what = 100;
                        mHandler.sendMessage(msg);
                        Looper.loop();*/
                    }else { // 快取中沒檔案
                        System.out.println("通過訪問網路把圖片資源獲取出來...");
                        URL url = new URL(path);
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        conn.setRequestMethod("GET");
                        int code = conn.getResponseCode();
                        if(code == 200){
                            InputStream is = conn.getInputStream();
                            // 暫存在記憶體裡的 圖片
                            Bitmap bitmap = BitmapFactory.decodeStream(is);
                            // 將這個圖片寫入到 cache 資料夾中
                            FileOutputStream fos = new FileOutputStream(file);
                            bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
                            fos.close();
                            is.close();

                            Message msg = Message.obtain();
                            msg.what = LOAD_IMAGE;
                            msg.obj = BitmapFactory.decodeFile(file.getAbsolutePath());
                            mHandler.sendMessage(msg);
                        }else {
                            /*Looper.prepare();
                            mHandler = new Handler(){
                                @Override
                                public void handleMessage(Message msg) {
                                    Toast.makeText(MainActivity.this,"獲取失敗", Toast.LENGTH_SHORT).show();
                                }
                            };
                            Looper.loop();*/
                            Message msg = Message.obtain();
                            msg.what = LOAD_ERROR;
                            msg.obj = "獲取圖片失敗,返回碼:" + code;
                            mHandler.sendMessage(msg);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Message msg = Message.obtain();
                    msg.what = LOAD_ERROR;
                    msg.obj = "獲取圖片失敗,拋異常!!" ;
                    mHandler.sendMessage(msg);
                }
            }
        }.start();
    }

    public void pre(View view) {
        currentPosition--;
        if (currentPosition < 0){
            currentPosition = paths.size() -1;
        }
        loadImageByPath(paths.get(currentPosition));
    }

    public void next(View view) {
        currentPosition++;
        if (currentPosition >= paths.size()){
            currentPosition = 0;
        }
        loadImageByPath(paths.get(currentPosition));
    }
}