1. 消息机制:
Message: 线程通信用于携带数据,数据载体
创建对象:Message.obtain(what)
属性:
public int what // id标识
int arg1
Object obj // 用于数据存储
when: 当前时间+ 延迟时间(如果有)【处理时间消息】
Handler target : 用来处理消息的Hander对象,就是发消息的Handler
Runnable callback: 用来处理消息的回调器(一般不用)【Runnable什么时候在子线程中执行,被new Thread(Runnable)的时候】
Message next: 指向下一个message的链表
Message sPool: 用来缓冲使用处理过的Message对象,以便复用
Handler:
Handler是 Message 的处理器,负责消息发送【把消息加入消息队列】和移除消息工作
sendMessage(Message msg) 发送消息
sendMessageDelayed(Message msg,long time): 发送延迟消息,不是延迟发送,而是立即发送,延迟处理
removeMessages:移除未处理的消息 【把消息从消息队列中移除】
MessageQueue: 优先级消息队列,先进先出
优先级队列:按照when排序的优先级队列
优先级队列:数据结构是链表, next指针指向下一个节点,更新的时候直接把链表断开指向其他的节点即可,不用排序
比如发送了A消息,发送了B,有发送了C,C延迟3次,那么C插入到队列最后
Looper: 循环器
负责循环取出MessageQueue中当前需要处理的消息.
交给对应的Handler 进行处理
处理以后,把Message缓存到消息池,后面备用
Message.obtain(what): 从消息池中取出Messaeg,而不是New
Handler机制:
Handler发送Message,放入消息队列MessageQueue, Looper从MeesageQueue中取出
Message, 调用Handler 处理 , 处理完毕清理 Message, 放入Meesage 消息池备用
//Handler 负责处理消息
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 100:
Toast.makeText(MainActivity.this,"chului",Toast.LENGTH_SHORT).show();
break;
}
}
};
public void testHander(){
new Thread(){
@Override
public void run() {
super.run();
// 从消息队列中取出消息
Message msg=Message.obtain();
// Msg 标识
msg.what= 100;
// msg 携带内容
msg.obj="携带内容";
// handler负责发送消息
handler.sendMessage(msg);
// 发消息之前首先移除,做倒计时的时候
// handler.removeMessages(100);
// handler.sendEmptyMessage(100);
}
}.start();
}
2. AsyncTask:
就是对Handler 和 Thread的封装,比tread效率更高,里面封装了线程池
如何使用:
onPreExecute // 在UI线程 显示loading
doInBackground // 在子线程 做耗时任务
onPostExecute(Void aVoid): // 执行完毕
如果doInBackground 下载时候要更新UI如何解决:
调用 publishProgress(len);
回调:
onProgressUpdate(Integer... values) 在UI线程
使用AsyncTask下载图片:
private File apkFile;
private ProgressDialog dialog;
Bitmap newBitmap=null;
public void testasync(){
new AsyncTask<Void,Integer,Void>(){
// 在UI线程
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
// storage/sdcard/Android/package_name/files/1.png
apkFile = new File(getExternalFilesDir(null), "1.png");
if(apkFile.exists()){
apkFile.delete();
}
super.onPreExecute();
}
// 在子线程
@Override
protected Void doInBackground(Void... params) {
try {
//1. 得到连接对象
String path = "http://192.168.2.110:8080/Web001/1.png";
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//2. 设置
//connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
//3. 连接
connection.connect();
//4. 请求并得到响应码200
int responseCode = connection.getResponseCode();
if(responseCode==200) {
//设置dialog的最大进度
dialog.setMax(connection.getContentLength());
//5. 得到包含APK文件数据的InputStream
InputStream is = connection.getInputStream();
// 如果是图片,不使用进度条,那么可以这么使用
// newBitmap=BitmapFactory.decodeStream(is);
//6. 创建指向apkFile的FileOutputStream
FileOutputStream fos = new FileOutputStream(apkFile);
//7. 边读边写
byte[] buffer = new byte[1024];
int len = -1;
while((len=is.read(buffer))!=-1) {
fos.write(buffer, 0, len);
//8. 显示下载进度
dialog.incrementProgressBy(len);
// 现在在子线程下载
// 如何更新UI进度条,调用这个方法,那么就会触发
// onProgressUpdate 方法在UI线程
publishProgress(len);
//休息一会(模拟网速慢)
//Thread.sleep(50);
SystemClock.sleep(50);
}
fos.close();
is.close();
}
//9. 下载完成, 关闭, 进入3)
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 在 UI线程
@Override
protected void onProgressUpdate(Integer... values) {
dialog.incrementProgressBy(values[0]);
super.onProgressUpdate(values);
}
// 执行完毕在主线程
@Override
protected void onPostExecute(Void aVoid) {
dialog.dismiss();
Bitmap bitmap= BitmapFactory.decodeFile(apkFile.getAbsolutePath());
myview.setImageBitmap(bitmap);
// myview.setImageBitmap(newBitmap);
super.onPostExecute(aVoid);
}
}
.execute();
}
效果:
3. Json使用
结构:
Json数组:[ value,value2] 相当于Java的数组
Json对象:{ key:value} 相当于Java的对象、或者Map
value数据类型:
数值 、字符串、null、jons数组 [] 、json对象 {}
** Json数据解析
Android原生 API只可以把 Json转化为对象
3.1.使用Android原生Api Json转实体类、 Json转List<X>
// Android原生Api JsontoBean
public void jsonToBean() throws JSONException{
String jsonString = "{\"id\":2, \"name\":\"大虾\"}";
JSONObject jsonObject=new JSONObject(jsonString);
int id= jsonObject.getInt("id");
String name = jsonObject.getString("name");
Person p=new Person(id,name);
Log.e("denganzhi",p.toString());
}
// Android原生Api Json转化为List<X>
public void jsonToLIstBean() throws JSONException {
String jsonString = "[{\"id\":3, \"name\":\"大虾\"},"
+ "{\"id\":5, \"name\":\"大虾2\"}]";
List<Person> list=new ArrayList<>();
JSONArray jsonArray=new JSONArray(jsonString);
for (int i=0;i<jsonArray.length();i++){
JSONObject jsonObject= jsonArray.getJSONObject(i);
int id= jsonObject.getInt("id");
String name = jsonObject.getString("name");
Person p=new Person(id,name);
list.add(p);
}
Log.e("denganzhi",list.toString());
}
3.2.使用Gson Json转实体类、 Json转List<X> 、Json 转化Map
//Gson 使用
public void sendMsg(View view) {
// Json转化为Json对象或者List对象
String jsonString = "{\"id\":2, \"name\":\"大虾\"}";
// 转化为实体类
Person p1 = new Gson().fromJson(jsonString,Person.class);
String jsonStringArr = "[{\"id\":3, \"name\":\"大虾\"},"
+ "{\"id\":5, \"name\":\"大虾2\"}]";
// 转化为List
List<Person> list = new Gson().fromJson(jsonStringArr,new TypeToken<List<Person>>(){}.getType());
Log.e("denganzhi","p1:"+p1);
Log.e("denganzhi",list.toString());
// 对象、List 转化为json字符串
Log.e("denganzhi",new Gson().toJson(p1));
// 问题,如果服务器修改了属性名,和本地实体类属性对不上, Json转化为Map
Map<String,Object> map=new Gson().fromJson(jsonString,new TypeToken<Map<String,Object>>(){}.getType());
testasync();
Log.e("denganzhi",new Gson().toJson(p1));
}