一、源码查看器
1.定义一个EditView用来输入网址,一个Button点击后查看,一个TextView来显示查看的源码
2.找到控件
et_path = (EditText) findViewById(R.id.et_path);
tv_result = (TextView) findViewById(R.id.tv_result);
3.定义将流转换为String的工具类
public class StreamTools {
//把InputStream转换成String
public static String readStream(InputStream in) throws Exception{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = -1;
byte[] buffer = new byte[1024];
while ((len=in.read(buffer))!=-1){
baos.write(buffer,0,len);
}
in.close();
String content = new String(baos.toByteArray());
return content;
}
}
4.定义点击事件
public void click(View v){
try {
//【2.1】获取路径
String path = et_path.getText().toString().trim();
if(path != null){
//【2.2】创建URL对象指定我们要访问的网址(路径)
URL url =new URL(path);
//【2.3】拿到HttpURLConnection对象 用于发送或接受数据
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//【2.4】设置发送get请求
conn.setRequestMethod("GET"); //GET大写
//【2.5】设置超时时间
conn.setConnectTimeout(5000); //5秒钟
//【2.6】获取服务器返回的状态码
int code = conn.getResponseCode();
//【2.7】如果code=200 说明请求成功
if(code == 200){
//【2.8】获取服务器返回的数据,是以流的形式返回的
InputStream in = conn.getInputStream();//由于把流转换成字符串是一个非常常见的操作,所以抽成一个工具类(utils)
//【2.9】使用我们定义的工具类把in转换成String
String content = StreamTools.readStream(in);
//【2.9.1】把流里面的数据展示到textview上
tv_result.setText(content);
}else {
Toast.makeText(MainActivity.this,"请求失败",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(MainActivity.this,"路径不能为空",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
5.在Android4.0之后,这个程序是不能正常运行的,看三、四
二、ScrollView控件(可滚动)
1.只能有一个孩子
2.若想有多个孩子可用一个布局包含多个控件,然后把布局放到ScrollView中
三、主线程(UI线程)
1.ANR异常(Application not response):应用无响应
2.如果在主线程中进行了耗时的操作(比如连接网络、拷贝大的数据、Thread.sleep() )
3.在android4.0以后,谷歌强制要求连接网络不能放到主线程中
4.避免ANR,可以把耗时的操作放到子线程中,自己再创建一个线程
5.只有主线程才能更新ui
四、消息机制(handler)
0.使用步骤
1)在主线程定义一个Handler
2)使用hadler会重写handler里面的handleMessage方法
3)拿着在主线程中创建的handler去子线程发消息
4)handlemessage方法就会执行 在这个方法里面去更新ui
1.在主线程中创建一个handler(助手)并重写handleMessage()方法
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
2.在点击事件中创建子线程,把链接网络的代码放到子线程中
public void click(View v){
//【2.0】创建一个子线程
new Thread(){public void run(){
}}.start();
}
3.把读取的数据放到Message对象中传到主线程
if(code == 200){
//【2.8】获取服务器返回的数据,是以流的形式返回的
InputStream in = conn.getInputStream();//由于把流转换成字符串是一个非常常见的操作,所以抽成一个工具类(utils)
//【2.9】使用我们定义的工具类把in转换成String
String content = StreamTools.readStream(in);
//创建Message对象
Message msg = new Message();
msg.obj = content;
handler.sendMessage(msg);//发了一条消息,把数据放到msg中,handlerMessage()方法就会执行
}
4.在主线程中更新ui
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
tv_result.setText(content);
}
};
5.原理
handler的作用是用来发消息和处理消息的
Looper 的作用是去消息队列里面取消息
Looper主线程一创建 Looper就有了
6.规则,不管什么版本的手机,只要做耗时的操作(比如联网、拷贝大数据等等)就自己开一个子线程,获取数据后想要更新ui,就用Handler就可以了
五、图片查看器
1.把TextView控件换为ImageView控件
2.使用handler发消息为
InputStream in = conn.getInputStream(); //获取流
Bitmap bitmap = BitmapFactory.decodeStream(in); //流转换为Bitmap
Message msg = Message.obtain(); //获取Message对象
msg.obj = bitmap;
handler.sendMessage(msg); //发送消息
3.更新ui
Bitmap bitmap=(Bitmap) msg.obj;
iv.setImageBitmap(bitmap);
六、对图片进行缓存
1.创建一个文件存放图片
File file = new File(getCacheDir(),"text.png");
2.判断文件是否存在
if(file.exists() && file.length()>0){ //判断文件是否存在
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); //如果存在,在文件中读取
Message msg = Message.obtain();
msg.obj = bitmap;
handler.sendMessage(msg);
}
3.不存在获取图片放到文件中,然后读取文件
else {
path = et_path.getText().toString().trim();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
if(code == 200){
InputStream in = conn.getInputStream();
//从流中读取然后写入文件
FileOutputStream fos = new FileOutputStream(file);
int len = -1;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.close();
in.close();
//在文件中读取图片
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Message msg = Message.obtain();
msg.obj = bitmap;
handler.sendMessage(msg);
}
}
七、cache和filedir区别
用户可以在应用设置内清空缓存(cache) ,若存放图片等不是很重要的数据用cache,存放重要数据信息用filedir
八、runOnUIThread()
1.这句api,不论在什么位置上调用action都运行在UI线程里
runOnUiThread(new Runnable() { //runOnUiThread接收的为Runable对象
@Override
public void run() {
iv.setImageBitmap(bitmap);
}
});
2.如果仅仅就是更新ui,就用runOnUiThread这个api就可以
有的时候可以通过Handler发送消息,携带数据,这时候必须得用handler
九、postDelayed
//两个参数,第一个Runnable对象,第二个时间
new Handler().postDelayed(new Runnable(){ //多事时间后开始执行run方法
@Override
public void run(){
}
},5000);