一、网页源码查看器
1.shift+F2调用httpwatch(为网页抓包数据分析工具【需下载】):
2.HttpURLConnection:用于发送和接收数据
3.必须有联网权限:android.permission.INTERNET
4.异常处理方式:
//若出现此种异常,
W/System.err(5504): android.os.NetworkOnMainThreadException
W/System.err(5504): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1148)
//在oncreate方法中加入
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
5.ScrollView(滚动条):使用注意:只能有一个孩子
二、消息机制的写法
1.如果在主线程中进行了耗时的操作(比如连接网络,拷贝数大的数据)。
2.避免出现anr异常可将耗时操作放置子线程中,自己创建一个线程。
3.4.0之后谷歌强制要求连接网络不能再主线程进行访问
4.只有主线程才可以更新ui
三、Handler原理
handler使用步骤:
1.在主线程定义一个Handler:private Handler handler = new Handler();
2.使用handler会重写Handler里面的handleMessage方法:public void handleMessage(android.os.Message msg) {};
3.拿着我们在主线程创建的Handler 去子线程发消息:handler.sendMessage(msg);
4.handleMessage方法就会执行,在这个方法里面去更新ui
handler作用:用来发消息和处理消息
looper作用:是去消息队列里面取消息,Looper是在主线程一创建,looper就有了。
网站源码查看器示例代码:
public class MainActivity extends Activity {
protected static final int REQUESTSUCCESS = 0; //变大写ctrl+shift+X 变小写写ctrl+shift+Y
protected static final int REQUESTFAILED= 1;
protected static final int REQUESTEXCEPTION = 2;
private EditText et_path;
private TextView tv_result;
//在主线程中定义一个Handler
private Handler handler = new Handler(){
//此方法在主线程中执行
public void handleMessage(android.os.Message msg) {
//所以可在主线程更新ui
switch (msg.what) {
case REQUESTSUCCESS:
String content = (String) msg.obj;
tv_result.setText(content);
break;
case REQUESTFAILED:
Toast.makeText(getApplicationContext(), "请求资源不存在", Toast.LENGTH_LONG).show();
break;
case REQUESTEXCEPTION:
Toast.makeText(getApplicationContext(), "服务器忙,请稍后再访问...", Toast.LENGTH_LONG).show();
break;
default:
break;
}
};
};
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
tv_result = (TextView) findViewById(R.id.tv_result);
// StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
// StrictMode.setThreadPolicy(policy);
System.out.println("当前线程的名称:"+Thread.currentThread().getName());
}
// 点击按钮查看,获取指定路径的源码
public void click(View v) {
// 2.0创建一个子线程
new Thread() {
public void run() {
try {
// 2.1获取源码路径
String path = et_path.getText().toString().trim();
// 2.2创建url对象,指定我们要访问的网址(路径)
URL url = new URL(path);
// 2.3拿到HttpURLConnection对象,用于发送或接收数据
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
// 2.4设置发送get请求
urlConnection.setRequestMethod("GET");// get要求大写,默认为get请求
// 2.5设置请求的超时时间
urlConnection.setConnectTimeout(5000);
// 2.6获取服务器返回的状态码 200请求成功
int code = urlConnection.getResponseCode();
if (code == 200) {
// 2.7获取服务器返回的数据,以流的形式返回
InputStream inputStream = urlConnection
.getInputStream();
String content = StreamTools.readStream(inputStream);
// 2.8.0创建Message对象
Message msg = new Message();
msg.what = REQUESTSUCCESS;
msg.obj = content;
// 2.8.1拿着我们创建的Handler助手,告诉系统,我们需要更新ui
handler.sendMessage(msg); // 发了一条消息,把消息放到msg里,handlerMessage方法执行
// 2.8将流的数据展示到TextView
// tv_result.setText(content);
} else {
// 请求资源不存在 Toast是一个view 也不能在子线程更新ui
Message msg = new Message();
msg.what = REQUESTFAILED; // 代表哪条消息
handler.sendMessage(msg);
}
} catch (Exception e) {
Message msg = new Message();
msg.what = REQUESTEXCEPTION; // 代表哪条消息
handler.sendMessage(msg);
e.printStackTrace();
}
}
}.start();
}
}
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]; //1kb
while((len = in.read(buffer))!= -1){
baos.write(buffer, 0, len);
}
in.close();
String content = new String(baos.toByteArray());
return content;
}
}
View Code
图片查看器(图片缓存)
1.把流信息转换为bitmap对象:
2.bitmapFactory.decodeStream(InputStream in);
3.加上网络访问权限:android.permission.INTERNET
public class MainActivity extends Activity {
private EditText et_path;
private ImageView iv;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
iv = (ImageView) findViewById(R.id.iv);
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
Bitmap bitmap = (Bitmap) msg.obj;
iv.setImageBitmap(bitmap);
};
};
// 点击按钮查看,获取指定路径的源码
public void click(View v) {
new Thread(){
public void run(){
try {
String path = et_path.getText().toString().trim();
//Base64.encodeToString(path.getBytes(), Base64.DEFAULT) 图片的文件名加密
File file = new File(getCacheDir(),Base64.encodeToString(path.getBytes(), Base64.DEFAULT));
//File file = new File(getCacheDir(),"test.png");
if(file.exists() && file.length()>0){
//使用缓存缓存的图片
System.out.println("使用缓存图片");
Bitmap cacheBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Message msg = Message.obtain(); //使用Message的静态方法可以减少对象的创建
msg.obj = cacheBitmap;
handler.sendMessage(msg);
}else{
//第一次访问,联网获取数据
System.out.println("第一次联网获取数据");
//2.1获取访问图片的路径
//String path = et_path.getText().toString().trim();
//创建url对象
URL url = new URL(path);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//2.4设置请求的方式
urlConnection.setRequestMethod("GET");
//2.5设置超时时间
urlConnection.setConnectTimeout(50000);
//2.6获取服务器返回的状态码
int code = urlConnection.getResponseCode();
if(code == 200){
//2.7获取图片的数据,不管什么数据(txt,图片文本)都是以流的形式返回
InputStream inputStream = urlConnection.getInputStream();
//2.7.1缓存图片 谷歌给我们提供了一个缓存目录
FileOutputStream fos = new FileOutputStream(file);
int len = -1;
byte[] buffer = new byte[1024];//1kb
while((len=inputStream.read(buffer))!=-1){
fos.write(buffer, 0, len);
}
fos.close();
inputStream.close();
//2.8通过位图工厂获取bitmap
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
//2.9把bitmap显示到iv上
Message msg = Message.obtain(); //使用Message的静态方法可以减少对象的创建
msg.obj = bitmap;
handler.sendMessage(msg);
//iv.setImageBitmap(bitmap);
}
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
View Code
四、runOnUiThread使用说明
1.如果仅是更新ui,则使用runOnUiThread可以。
2.可以通过handler发消息携带数据,必须用handler。
//不管在什么位置上调用action都运行在ui线程
runOnUiThread(new Runnable() {
//run方法一定执行在ui线程
@Override
public void run() {
// iv.setImageBitmap(bitmap);
}
});
注:此文为网站视频内容,本人在学习中,记录便于自己复习。