• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            羅朝輝(飄飄白云)

            關(guān)注嵌入式操作系統(tǒng),移動平臺,圖形開發(fā)。-->加微博 ^_^

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks

            Android多線程分析之一:使用Thread異步下載圖像

            羅朝輝 (http://www.shnenglu.com/kesalin/)

            本文遵循“署名-非商業(yè)用途-保持一致”創(chuàng)作公用協(xié)議

            打算整理一下對 Android Framework 中多線程相關(guān)知識的理解,主要集中在 Framework 層的 Thread, Handler, Looper, MessageQueue, Message, AysncTask,當(dāng)然不可避免地要涉及到 native 方法,因此也會分析 dalvik 中和線程以及消息處理相關(guān)的代碼:如 dalvik 中的 C++ Thread 類以及 MessageQueue 類。本文將從一個使用 Thread 的簡單 應(yīng)用入手,引入 Thread 這個話題,接下來的幾篇文章會依次介紹前面提到的那些主題。

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

            布局文件很簡單,一個 Button,一個 ImageView:
            <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:padding
            ="10dip" >

                <Button
                    
            android:id="@+id/LoadButton"
                    android:layout_width
            ="fill_parent"
                    android:layout_height
            ="wrap_content"
                    android:text
            ="Load">
                </Button>

                <ImageView
                    
            android:id="@+id/ImageVivew" 
                    android:layout_width
            ="match_parent" 
                    android:layout_height
            ="400dip" 
                    android:scaleType
            ="centerInside" 
                    android:padding
            ="2dp">
                </ImageView> 
                
            </LinearLayout>

            接下來看代碼:

            首先是定義圖片的 url 路徑,兩個消息值以及一些控件:

                private static final String sImageUrl = "http://fashion.qqread.com/ArtImage/20110225/0083_13.jpg";

                private static final int MSG_LOAD_SUCCESS = 0;
                private static final int MSG_LOAD_FAILURE = 1;
                
                private Button mLoadButton;
                private ProgressDialog mProgressBar;
                private ImageView mImageView;

            然后來看控件的設(shè)置:
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
                    
                    Log.i("UI thread", " >> onCreate()");
                    
                    mProgressBar = new ProgressDialog(this);
                    mProgressBar.setCancelable(true);
                    mProgressBar.setMessage("Image downloading ");
                    mProgressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                    mProgressBar.setMax(100);
                    
                    mImageView = (ImageView)this.findViewById(R.id.ImageVivew);
                    
                    mLoadButton = (Button)this.findViewById(R.id.LoadButton);
                    mLoadButton.setOnClickListener(new View.OnClickListener() {
                        @Override 
                        public void onClick(View v) {
                            mProgressBar.setProgress(0);
                            mProgressBar.show();
                            
                            new Thread() {
                                @Override
                                public void run() {
                                    Log.i("Load thread", " >> run()");
                                    Bitmap bitmap = loadImageFromUrl(sImageUrl);
                                    if (bitmap != null) {
                                        Message msg = mHandler.obtainMessage(MSG_LOAD_SUCCESS, bitmap);
                                        mHandler.sendMessage(msg);
                                    }
                                    else {
                                        Message msg = mHandler.obtainMessage(MSG_LOAD_FAILURE, null);
                                        mHandler.sendMessage(msg);
                                    }
                                }
                            }.start();
                        }
                    });
                }

            loadImageFromUrl 是一個從網(wǎng)絡(luò)下載 Bitmap 的 static 函數(shù):
                static Bitmap loadImageFromUrl(String uil) {
                    Bitmap bitmap = null;
                    try{
                        InputStream in = new java.net.URL(sImageUrl).openStream();
                        bitmap = BitmapFactory.decodeStream(in);
                        in.close();
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                    return bitmap;
                }

            mHandler 是主線程也就是 UI 線程處理自定義消息的 Handler:
                private Handler mHandler= new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        Log.i("UI thread", " >> handleMessage()");
                        
                        switch(msg.what){
                        case MSG_LOAD_SUCCESS:
                            Bitmap bitmap = (Bitmap) msg.obj;
                            mImageView.setImageBitmap(bitmap);
                            
                            mProgressBar.setProgress(100);
                            mProgressBar.setMessage("Image downloading success!");
                            mProgressBar.dismiss();
                            break;
                            
                        case MSG_LOAD_FAILURE:
                            mProgressBar.setMessage("Image downloading failure!");
                            mProgressBar.dismiss();
                            break;
                        }
                    }
                };

            縱觀上面的代碼,當(dāng)點擊 load 按鈕時,會創(chuàng)建一個匿名 Thread,并調(diào)用其 start() 啟動運行線程,在這個線程中進行圖像下載并解碼成 Bitmap,然后通過 Handler 向 UI 線程發(fā)送消息以通知下載結(jié)果。這都是在匿名 Thead 中處理的。主線程也就是 UI 線程收到消息之后,會分發(fā)給 Handler,在它的 handleMessage 方法中根據(jù)消息 id 來處理下載結(jié)果,要么成功要么失敗,并相應(yīng)地更新 UI。

            運行該示例



            可以從 logcat 的地四欄中看到 UI thread(tid: 817) 和 Load thread(tid: 830) 的線程 id 是不同的,因為它們是兩個獨立的線程。


            在匿名線程下載完畢之后,為什么不直接在這個線程的 run() 中更新 UI 呢?這樣做有什么后果?這些問題將在后文詳細(xì)解答。

            posted on 2014-07-10 09:22 羅朝輝 閱讀(1890) 評論(0)  編輯 收藏 引用 所屬分類: 移動開發(fā)
            久久免费视频观看| 亚洲国产精品无码久久青草 | 色综合久久88色综合天天 | 久久99精品国产麻豆不卡| 亚洲国产成人精品91久久久| 亚洲精品tv久久久久久久久| 久久福利青草精品资源站| 亚洲综合久久久| 久久综合综合久久狠狠狠97色88| 欧美日韩中文字幕久久久不卡| 亚洲国产另类久久久精品黑人| 99久久久久| 久久国产精品成人免费| 人妻精品久久久久中文字幕| 久久99精品国产99久久| 亚洲乱码中文字幕久久孕妇黑人| 久久99久久无码毛片一区二区| aaa级精品久久久国产片| 伊人久久大香线蕉AV一区二区| 91精品久久久久久无码| 久久久精品人妻一区二区三区蜜桃| 日产久久强奸免费的看| 精品久久久无码中文字幕天天| 久久99精品久久久久婷婷| 色婷婷综合久久久久中文字幕| 国产福利电影一区二区三区久久老子无码午夜伦不 | 国产精品美女久久久网AV| 国产色综合久久无码有码| 久久福利片| 久久精品一区二区影院| 久久久久国产一级毛片高清版| 婷婷五月深深久久精品| 欧美熟妇另类久久久久久不卡 | 久久艹国产| 日韩久久无码免费毛片软件 | 精品久久久久久无码国产| 久久精品无码一区二区三区免费| 亚洲成人精品久久| 久久99精品久久久久久水蜜桃| 欧美大战日韩91综合一区婷婷久久青草| 91精品国产综合久久四虎久久无码一级|