需求 : 获取网络上的一张图片并显示在手机界面上.
注意 :
1,ANR异常 :
应用程序无响应异常,访问服务器时,服务器挂掉,就会出现这种异常,可以在子线程中访问网络来避免这种异常.
2,android.os.NetworkOnMainThreadException异常:
在Android 4.0以后,不允许在主线程中进行访问网络的操作,只能在子线程中进行网络的访问,否则会报该异常。
3,android.view.ViewRoot$CalledFromWrongThreadException 异常:
在子线程中不允许进行修改界面的操作,只能在主线程中修改界面,否则会报该异常。
所以,进行网络访问,连接服务器获取图片的操作,只能放在子线程中进行了。而获取控件进行界面修改的操作只能放在主线程中了。
所以,必须将获得的图片对象从子线程中传到主线程中去,这就要用到了Handler机制了。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
需求 :
* 首先,定义个方法 getBitmapFromNet ,专门用来进行访问网络,获得图片的操作.
步骤 :
* 1,将图片的地址变成个URL对象。
* 2,通过该URL对象得到个HttpURLConnection连接对象。
* 3,给该连接对象设置好请求方式,连接超时的时间,以及读取内容超时的时间,然后开始连接服务器。
* 4,获得该链接的返回码。
* 5,如果该返回码为200,则表示连接服务器成功,那么就获取该连接的输入流。
* 6,在Android中有个方法可以直接将关联图片的输入流变成个图片对象,使用该方法获得该图片对象。
getBitmapFromNet方法的代码:
//定义一个函数用来专门进行访问网络的操作,获取图片
public Bitmap getBitmapFromNet(String url)
{
try {
//1,将图片的地址转换成个URL对象
URL u = new URL(url);
//2,通过该URL对象得到个HttpURLConnection的连接对象
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
//3,给该连接对象设置好请求方式,连接超时的时间,读取数据的超时时间,然后开始连接服务器
conn.setRequestMethod("GET");//请求方式必须大写
conn.setConnectTimeout(5000);//连接超时的时间为5s
conn.setReadTimeout(5000);//读取数据超时的时间为5s
conn.connect();//连接服务器
//4,获得该连接的返回码
int responseCode = conn.getResponseCode();
//5,如果该返回码为200,那么就表示连接成功,开始获得该连接的输入流
if(responseCode == 200)
{
InputStream is = conn.getInputStream();
//6,将获得的输入流转换成一个图片对象,并将图片对象返回
Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
需求 : 将获得的图片显示到手机界面上
思路 :
* A,定义好布局,添加好权限
* B,因为在4.0后,访问网络的操作只能放在子线程中,且又因为修改界面的操作只能放在主线程中
* 所以,就在子线程中访问网络获取图片对象.
* C,在主线程中定义个Handler,并实现handleMessage方法,
* D,在子线程中将图片用Handler发送到主线程来
* E,在主线程的handleMessage中接收子线程发来的图片对象,并且将图片显示在界面上.
代码 :
public class MainActivity extends Activity {
ImageView image = null;
EditText editText = null;
//C ,定义个Handler对象,并重写handleMessage方法
Handler handler = new Handler(){
public void handleMessage(Message msg) {
//E,开始接收子线程发来的图片对象,并将图片显示在ImageView界面上
Bitmap bitmap = (Bitmap) msg.obj;
image.setImageBitmap(bitmap);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//首先获得相应的控件
image = (ImageView) findViewById(R.id.imageView);
editText = (EditText) findViewById(R.id.textId);
}
//点击事件的方法
public void onClick(View v)
{
//获得输入框中的地址
final String url = editText.getText().toString();
//获取网络上的图片
//进行访问网络的操作,在4.0后只能放在子线程中来做
new Thread(new Runnable(){
public void run() {
//B,在子线程中进行访问网络获取图片的操作
Bitmap bitmap = getBitmapFromNet(url);
//D,使用Handler机制将图片从子线程发送到主线程去
Message msg = new Message();
msg.obj = bitmap;
handler.sendMessage(msg);
}
}).start();
}
}