在老版本的android里,主线程可以不考虑用户体验,可以将耗时操作放在里面。而正确的做法是把耗时操作另外写入子线程里,这样程序就不会崩溃
通过Http的Get方式获取数据
(自定义子线程在主函数调用,注意要获取联网权限)
public class testThread extends Thread {
public Bitmap bm;
public void run(){
String path = "http://169.254.165.163:8080/mm.jpg";
try {
URL url = new URL(path);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.connect();
InputStream is = connection.getInputStream();
bm = BitmapFactory.decodeStream(is);
} catch (Exception e) {
}
}
}
第二种写法:
public class testThread extends Thread {
public Bitmap bm;
public void run(){
String path = "http://169.254.165.163:8080/mm.jpg";
try {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.connect();
if(connection.getResponseCode()==200){
InputStream is = connection.getInputStream();
bm = BitmapFactory.decodeStream(is);
}
else{
}
} catch (Exception e) {
}
}
}
此时注意想要获取线程中的数据
需要额外通过调用thread.join()函数使他执行结束
要在除主函数以外的地方刷新ui,需要认识消息队列
在主线程创建的时候会自动生成一个消息队列MessageQueue和轮询器Looper对象
在MainActivity中,创建一个Handler对象复写其中的handleMessage(android.os.Message msg)方法,然后在需要刷新ui时调用这个handler对象方法sendMessage(),发送一条消息到消息队列,looper会自动交给handler处理,其中处理的方法就是自己复写的那个
public class MainActivity extends Activity {
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//在这里刷新ui
switch (msg.what) {
case 1:
ImageView iv = (ImageView)findViewById(R.id.iv);
iv.setImageBitmap((Bitmap)msg.obj);
break;
case 2:
Toast.makeText(MainActivity.this, "获取失败", 0).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
Thread thread = new Thread(){
public void run() {
try {
String path = "http://169.254.165.163:8080/mm.jpg";
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.connect();
if(connection.getResponseCode()==200){
InputStream is = connection.getInputStream();
Bitmap bm = BitmapFactory.decodeStream(is);
Message message = new Message();
message.obj = bm;
message.what = 1;
handler.sendMessage(message);
}else{
Message msg = handler.obtainMessage();//复用空闲的消息
msg.what = 2;
handler.sendMessage(msg);
}
} catch (Exception e) {
}
};
};
thread.start();
}
}
注意xml文件解析
添加网络图片缓存功能(即将输入流is通过文件输出流写入本地文件,再将文件工厂解析改为解析文件)
byte[] b = new byte[1024];
int len;
FileOutputStream fos = new FileOutputStream(file);
while((len=is.read(b))!=-1){
//这里如果用write(b)方法图片会显示出错,因为最后一次写入依然是1024字节
fos.write(b,0,len);
}
fos.close();
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
本地有文件之后就可以获取前判断
if(file.exists()){
Log.e("sony", "从本地获取");
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
Message message = new Message();
message.obj = bm;
message.what = 1;
handler.sendMessage(message);
}
else{
//获取网络字节写入本地图片
}
获取开源代码(别人写好的类)
去github搜索英文关键词,下载使用
查看网页源码
先通过字节数组读取is写入到字节数组输出流,再将字节数组输出流转化为String类型,通过handler刷新ui
public class myThread extends Thread{
private Handler handler;
public myThread(Handler handler) {
this.handler = handler;
}
@Override
public void run() {
try {
URL url = new URL("http://169.254.113.102:8080/baidu.html");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(8000);
conn.setReadTimeout(8000);
conn.connect();
if(conn.getResponseCode()==200){
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len=is.read(b))!=-1){
bos.write(b,0,len);
}
String text = bos.toString("UTF-8");
Message msg = new Message();
msg.obj = text;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结:你输入的类型是html文件还是图片,就用对应的文件输出流或者字节输出流解析,达到解析效果