上篇遺留下來一個問題就是:顯示網絡圖片,我用android2.3的系統,能夠顯示圖片出來,而且若是圖片比較大,應用會卡的現象,確定是由於使用主線程去獲取網絡圖片形成的,但若是我用android4.0以上的系統運行,則不能顯示圖片,只顯示小方框。html
究其緣由,是在4.0的系統上執行的時候報錯了,異常是:android.os.NetworkOnMainThreadException 通過查文檔,原來是4.0系統不容許主線程(UI線程)訪問網絡,所以致使了其異常。說白了就是在主線程上訪問網絡,會形成主線程掛起,系統不容許使用了。android
看到Android4.0不容許主線程(UI線程)訪問網絡,立馬腦子就想起來 ,不能用主線程訪問,能夠開另一個線程,把圖片下到本地sd卡中,以後在賦值到TextView裏面。不急着來代碼,我和你們在把這個邏輯在理一下:獲取圖片路徑——異步下載圖片——完成下載後從新賦值Textview網絡
想到這裏,我就準備本身親自實踐下......因而,我就簡單的寫了文件下載類DownLoadUtils,有四個事件就是開始下載,下載中(返回進度),完成下載後,下載出錯!具體代碼就不貼出來了。你們能夠本身去寫一個,下載文件的代碼搜下都有!下載類裏面用到了線程和Handler的的使用,下篇我具體講下這個。異步
下面是Activity頁面處理代碼:ide
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());
若是沒有下載就開啓一個下載線程spa
downLoadUtils.download(source, path+String.valueOf(source.hashCode()));
第二個重點就是監聽下載完成事件,完成下載之後,從新給Textview賦值線程
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裏面。在網絡正常的狀況下,若是是相同圖片只須要下載一次,這樣能夠節省了手機的流量。code
我還有一種解決方案就是不須要給Textview賦兩次值,就是首先解析出來圖片路徑,而後下載圖片,最後賦值給Textview,其實道理是同樣的,以前的作法是經過重載方法解析出來圖片的路徑而後下載圖片。只不過是多了一個賦值,沒有任何影響。你們有好的思路,也能夠介紹下。htm