Android 学习心得(5)——访问网络图片并显示
主类
1 package com.example.b_app; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.InputStream; 5 import java.net.HttpURLConnection; 6 import java.net.URL; 7 8 import android.support.v7.app.ActionBarActivity; 9 import android.annotation.SuppressLint; 10 import android.graphics.Bitmap; 11 import android.graphics.BitmapFactory; 12 import android.os.Bundle; 13 import android.os.Handler; 14 import android.os.Message; 15 import android.widget.ImageView; 16 import android.widget.Toast; 17 18 public class MainActivity extends ActionBarActivity { 19 private String Path="http://pic1.ooopic.com/uploadfilepic/sheji/2009-05-05/OOOPIC_vip4_20090505079ae095187332ea.jpg"; 20 private ImageView mImageView; 21 private Bitmap bitmap; 22 //定义Handler对象 23 @SuppressLint("HandlerLeak") 24 private Handler handler =new Handler(){ 25 @Override 26 //当有消息发送出来的时候就执行Handler的这个方法 27 public void handleMessage(Message msg){ 28 super.handleMessage(msg); 29 //处理UI 30 mImageView.setImageBitmap(bitmap); 31 } 32 33 }; 34 35 36 @Override 37 protected void onCreate(Bundle savedInstanceState) { 38 super.onCreate(savedInstanceState); 39 setContentView(R.layout.activity_main); 40 mImageView = (ImageView) this.findViewById(R.id.mImageView); 41 //新建一个子线程以异步访问网络 42 //之所以这样处理是因为我采用Android4.3的虚拟机 不允许在主线程中执行网络访问 43 new Thread(new Runnable() { 44 45 @Override 46 public void run() { 47 URL url; 48 try { 49 url = new URL(Path); 50 51 52 //请求http连接-得到HttpURLConnection对象 53 HttpURLConnection urlConn=(HttpURLConnection)url.openConnection(); 54 //通过http得到网络图片--设置请求方式 get/post 55 urlConn.setRequestMethod("GET"); 56 //设置连接超时-----设置为5秒钟 57 urlConn.setConnectTimeout(20*1000); 58 //从外界向手机内部传送数据----通过输入流获取图片数据 59 InputStream in = urlConn.getInputStream(); 60 //将数据存入缓冲区----定义一个缓冲区 61 ByteArrayOutputStream out = new ByteArrayOutputStream(); 62 //设置缓冲区大小为1024bit 63 byte[] buffer = new byte[1024]; 64 //不断从流李循环读取数据 督导末尾的时候 65 //当len的值等于-1的时候说明流读取到达末尾 66 int len = 0; 67 while((len=in.read(buffer))!=-1){ 68 out.write(buffer, 0, len); 69 } 70 //取得数据 71 byte[] data = out.toByteArray(); 72 //关闭流 73 in.close(); 74 out.close(); 75 //将二进制数据转换成位图 76 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 77 //向handler发送一条空消息执行handler的方法异步处理 78 79 handler.sendEmptyMessage(0); 80 } catch (Exception e) { 81 //出现异常则显示吐司消息 82 Toast.makeText(getApplicationContext(), "连接超时!", Toast.LENGTH_LONG).show(); 83 } 84 85 86 } 87 }).start(); 88 89 } 90 } 91 92
配置文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.b_app" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="19" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name="com.example.b_app.MainActivity" 18 android:label="@string/app_name" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 26 </application> 27 <uses-permission android:name="android.permission.INTERNET" /> 28 29 </manifest>
界面文件
1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/container" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 tools:context="com.example.b_app.MainActivity" 7 tools:ignore="MergeRootFrame" > 8 9 <ImageView android:layout_width="wrap_content" 10 android:contentDescription="@string/img" 11 android:layout_height="wrap_content" 12 android:id="@+id/mImageView"/> 13 14 </FrameLayout>
编译过程中出现的错误1:android.os.NetworkOnMainThreadException
错误原因: Android在4.0之前的版本 支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。
解决方案:使用线程处理(代码中已经给出)
编译过程中出现的错误2:Only the original thread that created a view hierarchy can touch its views.
错误原因:android中UI不是线程安全的。
解决方案:使用handler处理(代码中已经给出)
我是个大懒虫,能写一个字我绝不写两个字。