一、主线程与ANR
*、主线程,
android的设计思路,只有一个线程对界面做出修改。
所有activity代码都运行在主线程。
其他线程对UI修改会导致异常。
*、ANR 应用失去响应,成因和避免
*耗时操作: 网络连接和网络数据获取,对存储器读写,对大量数据的计算,
二、android的消息机制 (Handler与Message)
*、android的消息机制 注意:message传送数据都用Bundle
由于ANR,android需要一种机制使其他线程操作完后通知主线程更新界面
android采用一种消息机制来刷新界面
大部分操作,时间最终都是产生消息来实现通知界面的
对消息队列Looper的操作只能通过handler来进行
*、当调用Handler的sendMessage的方法时就能插入一个消息
*、主线程Looper会发现消息队列的改变,并作出这个消息的响应
*、消息响应后会从消息队列Looper中移除
通过那个Handler发布信息,那个Handler也会负责处理这条信息
*、处理过程中包含调用Handler的handleMessage方法
*、通过override这个方法来实现消息的处理、
*、这个方法时运行在主线程中的
Handler常用方法:
sendEmptyMessage(int what) 发送只有一个what值的消息
sendMessage: 向Looper发送插入一个消息,handleMessage中处理
sendMessageDelayed(Message msg,long delayMillis)延时发送Message
dispatchMessage 系统对Looper中的信息作出响应
haldleMessage(Message message) 用户定义用户对Looper中的信息作出响应
removeMessage(int what)删除/取消定时Message
Message 成员:
int what 消息类型,区分发生了什么事件,eg:ok error
int arg1 事件对应的简单整形数据1
int arg2 事件对应的简单整形数据2
Object obj 事件对应的数据
*、Message与Handler
*、Thread与Handler
eg:
public class MainActivity extends AppCompatActivity {
Button start,stop;
ProgressBar progressBar;
private static final int pstart = 1; public int num = 0;
//private static final int pstop = 2;
//新建一个消息响应Handler 类对象
Handler handler= handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle = msg.getData();
int progress = bundle.getInt("setProgress");
progressBar.setProgress(progress);
handler.postDelayed(thread,1000);
}
};
// final MyThread thread = new MyThread();
MyThread thread = new MyThread();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//关联控件
init();
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(thread);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(thread);
}
});
}
/**
* 关联控件
*/
private void init(){
start = (Button)findViewById(R.id.button);
stop = (Button)findViewById(R.id.button2);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
}
class MyThread implements Runnable{
//private boolean flog = true;
@Override
public void run() {
num+=5;
if (num==100){
num=0;
}
//创建消息
Message message = new Message();
message.what=pstart;
Bundle bundle = new Bundle();
bundle.putInt("setProgress",num);
message.setData(bundle);
handler.sendMessage(message);
}
/* @Override
public synchronized void start() {
flog=true;
super.start();
}
public void stopThread(){
flog = false;
}
*/
/* @Override
public void run() {
while (true){
num+=5;
if (num==100){
num=0;
}
//创建消息
Message message = new Message();
message.what=pstart;
Bundle bundle = new Bundle();
bundle.putInt("setProgress",num);
message.setData(bundle);
handler.sendMessage(message);
//睡眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
super.run();
}*/
}
}
三、AsyncTask(重点)
特点:AsyncTask是有系统来创建和删除执行任务的新城,并有效的管理它们。
开发者、只要创建AsyncTask的子类,实现响应方法,再创建AscynTask子类的对象,并执行
execute方法
AsyncTask:执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现至少一个方法,
*onPreExecute(): 方法在执行实际的后台操作前被主线程调用。可以在该方法中做一些
准备工作,
*、doInBackground(Params..);将在onPreExecute方法执行后马上执行,该方法运行在后台
线程中。这里主要负责执行耗时的后台工作,该方法是抽象方法,子类必须实现。方法中可以调用publishProgress方法来实时跟新界面。
*、onProgressUpdate(Progress..) 在publishProgress方法被调用后,执行此函数,
UI线程将调用这个方法,在界面上展示任务进度情况。
*、onPostExecute(Result):在doInBackground执行完成后,此方法被主线程次奥用,
工作线程的运行结果将通过该方法传递到主线程。
AsyncTask遵循规则:
*、Task实例必须在主线程中创建。execute方法必须在主线程中调
*、不要手动调用AsyncTask中的方法。
*、一个AsyncTaskTask只能被执行一次,否则多次调用会出现异常。
eg:
class MyAsyncTask extends AsyncTask<String,Void,Void>{
Bitmap bitmap ;
@Override
protected Void doInBackground(String... params) {
Log.i( "tian",params[0 ]);
HttpGet get = new HttpGet(params[0]);
HttpClient client = new DefaultHttpClient();
try {
//通过HttpResponse获得数据
HttpResponse response = client.execute(get);
//使用EntityUtils.toString 方法转化获得数据的格式
String message = EntityUtils. toString(response.getEntity(), "UTF-8");
//Log.i("tian",message);
//
JSONObject job = new JSONObject(message);
JSONArray ja = job.getJSONArray("result");
for (int i = 0; i < ja.length(); i++) {
JSONObject jobday = ja.getJSONObject(i);
//获得星期几
String week = jobday.getString("week");
//获得天气
String weather = jobday.getString("weather");
//获得图片的地址,并得到一个Bitmap对象
String bitmapurl = jobday.getString("weather_icon");
URL url = new URL(bitmapurl);
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
bitmap = BitmapFactory. decodeStream(is);
//获得温度信息
String temperature = jobday.getString("temperature");
//获得风力信息
String wind = jobday.getString("wind");
Weather weather1 = new Weather(week,weather, bitmap,temperature,wind);
wlist.add(weather1);
}
Log.i( "tian", wlist .size()+"");
}catch(MalformedURLException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(JSONException e){
e.printStackTrace();
}
return null ;
}
@Override
protected void onPostExecute(Void aVoid) {
show = (ListView)findViewById(R.id.listView);
show .setAdapter(new MyAdapter());
super .onPostExecute(aVoid);
}
}
多线程与异步通讯、、、、主要是AsyncTask
最新推荐文章于 2024-08-21 10:01:13 发布