Android中Textview顯示帶html文本三——-【Textview顯示網狀圖片】

來源:互聯網
上載者:User

上篇我講了Textview顯示本地圖片,具體請看Android中Textview顯示帶html文本二-------【Textview顯示本地圖片】

上篇遺留下來一個問題就是:顯示網狀圖片,我用android2.3的系統,可以顯示圖片出來,並且如果圖片比較大,應用會卡的現象,肯定是因為使用主線程去擷取網狀圖片造成的,但如果我用android4.0以上的系統運行,則不能顯示圖片,只顯示小方框。

究其原因,是在4.0的系統上執行的時候報錯了,異常是:android.os.NetworkOnMainThreadException 經過查文檔,原來是4.0系統不允許主線程(UI線程)訪問網路,因此導致了其異常。說白了就是在主線程上訪問網路,會造成主線程掛起,系統不允許使用了。

看到Android4.0不允許主線程(UI線程)訪問網路,立馬腦子就想起來 ,不能用主線程訪問,可以開另外一個線程,把圖片下到本地sd卡中,之後在賦值到TextView裡面。不急著來代碼,我和大家在把這個邏輯在理一下:擷取圖片路徑——非同步下載圖片——完成下載後重新賦值Textview

想到這裡,我就準備自己親自實踐下......於是,我就簡單的寫了檔案下載類DownLoadUtils,有四個事件就是開始下載,下載中(返回進度),完成下載後,下載出錯!具體代碼就不貼出來了。大家可以自己去寫一個,下載檔案的代碼搜下都有!下載類裡面用到了線程和Handler的的使用,下篇我具體講下這個。

下面是Activity頁面處理代碼:

View Code

private TextView tView;    private DownLoadUtils downLoadUtils;    //儲存檔案路徑    private final String path="/mnt/sdcard/downimg";    //設定text的值    String sText = "測試圖片資訊:<br><img src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" />";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.mxgsa_activity);        findControl();        setData();    }    private void findControl() {        tView = (TextView) findViewById(R.id.tvImage);    }        private void setData() {        //初始化下載類        downLoadUtils=new DownLoadUtils();        //設定下載類監聽事件        downLoadUtils.setOnDownloadListener(onDownloadListener);        //給Textview賦值        tView.setText(Html.fromHtml(sText, imageGetter, null));    }    final Html.ImageGetter imageGetter = new Html.ImageGetter() {        public Drawable getDrawable(String source) {            Drawable drawable = null;            String fileString=path+String.valueOf(source.hashCode());            Log.i("DEBUG", fileString+"");            Log.i("DEBUG", source+"");            //判斷SD卡裡面是否存在圖片檔案            if (new File(fileString).exists()) {                Log.i("DEBUG", fileString+"  eixts");                //擷取本地檔案返回Drawable                drawable=Drawable.createFromPath(fileString);                //設定圖片邊界                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());                return drawable;            }else {                Log.i("DEBUG", fileString+" Do not eixts");                //啟動新線程下載                downLoadUtils.download(source, path+String.valueOf(source.hashCode()));                return drawable;            }                    };    };    OnDownloadListener onDownloadListener=new OnDownloadListener() {                //下載進度        public void onDownloadUpdate(DownLoadUtils manager, int percent) {            // TODO Auto-generated method stub            Log.i("DEBUG", percent+"");        }                //下載失敗        public void onDownloadError(DownLoadUtils manager, Exception e) {            // TODO Auto-generated method stub                    }                //開始下載        public void onDownloadConnect(DownLoadUtils manager) {            // TODO Auto-generated method stub            Log.i("DEBUG", "Start  //////");        }                //完成下載        public void onDownloadComplete(DownLoadUtils manager, Object result) {            // TODO Auto-generated method stub            Log.i("DEBUG", result.toString());            //替換sTExt的值,就是把圖片的網路路徑換成本地SD卡圖片路徑(最早想法,可以不需要這樣做了)            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));            //再一次賦值給Textview            tView.setText(Html.fromHtml(sText, imageGetter, null));        }    };

下面來簡單的介紹下上面的代碼,最重要的就是有兩點,就是第一次把sText賦值Textview,在Html.ImageGetter的重載方法裡面去判斷該圖片檔案是否已經下載,如果已經下載,就直接讀取SD卡裡面的圖片檔案,如上篇所講的Textview顯示本地圖片,

//擷取本地檔案返回Drawable                drawable=Drawable.createFromPath(fileString);                //設定圖片邊界                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

如果沒有下載就開啟一個下載線程

//啟動新線程下載
downLoadUtils.download(source, path+String.valueOf(source.hashCode()));

第二個重點就是監聽下載完成事件,完成下載以後,重新給Textview賦值

View Code

OnDownloadListener onDownloadListener=new OnDownloadListener() {                //下載進度        public void onDownloadUpdate(DownLoadUtils manager, int percent) {            // TODO Auto-generated method stub            Log.i("DEBUG", percent+"");        }                //下載失敗        public void onDownloadError(DownLoadUtils manager, Exception e) {            // TODO Auto-generated method stub                    }                //開始下載        public void onDownloadConnect(DownLoadUtils manager) {            // TODO Auto-generated method stub            Log.i("DEBUG", "Start  //////");        }                //完成下載        public void onDownloadComplete(DownLoadUtils manager, Object result) {            // TODO Auto-generated method stub            Log.i("DEBUG", result.toString());            //替換sTExt的值,就是把圖片的網路路徑換成本地SD卡圖片路徑(最早想法,可以不需要這樣做了)            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));            //再一次賦值給Textview            tView.setText(Html.fromHtml(sText, imageGetter, null));        }    };

這樣做了之後,網狀圖片就可以顯示在Textview裡面。在網路正常的情況下,如果是相同圖片只需要下載一次,這樣可以節省了手機的流量。

我還有一種解決方案就是不需要給Textview賦兩次值,就是首先解析出來圖片路徑,然後下載圖片,最後賦值給Textview,其實道理是一樣的,之前的做法是通過重載方法解析出來圖片的路徑然後下載圖片。只不過是多了一個賦值,沒有任何影響。大家有好的思路,也可以介紹下。

以上觀點只代表我個人意見。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.