刚学Android没多久哈,所以好多运行中的机制不是很清楚呢>_<
1、Android中如果创建了一个主Activity,也就是创建了一个主线程,那这个主线程有没有run方法?还有如果在Activity的onCreate方法中给button设置了监听,后面点击按钮出发Click事件,那个onCreate方法并没有再次执行,为什么还是能执行onCreate方法中的onClick方法呢?
2、还在就是如果我在主线程中创建一个Handler并且就是绑定到这个主线程的Looper上的(先不管这个有没有实际意义哈,我知道handler用在线程间消息传递才能看出他的强大哈~),具体情况请看一下下面的代码:
package com.test.handler;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;public class ChildSet extends Activity {
/** Called when the activity is first created. */
private ProgressBar myProgressbar;
private Button myButton;
private OnClickListener listener;
private Runnable childThread;
private static final String TAG = "TAG";
Myhandler mainHandler, childHandler;
private int i = 0; // private Thread t; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); myProgressbar = (ProgressBar) findViewById(R.id.progressbar_id);
myButton = (Button) findViewById(R.id.button_id); Log.i(TAG, "Main Thread:" + Thread.currentThread().getName());
// HandlerThread handlerThread = new HandlerThread("child_ron_Thread");
// handlerThread.start(); mainHandler = new Myhandler(Looper.getMainLooper());
// childHandler = new Myhandler(handlerThread.getLooper());// $$$$$$$$$$$$$ myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (i == 0) {
myProgressbar.setVisibility(ProgressBar.VISIBLE);
mainHandler.post(childThread);
i = i + 1;
}
// myProgressbar.setProgress(80);//这个可以设置的哟~~~
Log.i(TAG, "Click..." + Thread.currentThread().getName());
}
});
childThread = new Runnable() {
int persent = 0; @Override
public void run() {
// TODO Auto-generated method stub
persent += 5;
Message msg = Message.obtain();
msg.arg1 = persent;
Log.i(TAG, "Runnable Thread:"
+ Thread.currentThread().getName()); // mainHandler.sendMessage(msg);
mainHandler.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
};
} // //////////////////////////onCreate////////////////////////////
class Myhandler extends Handler {
public Myhandler(Looper looper) {
super(looper);
} public void handleMessage(Message msg) {
myProgressbar.setProgress(msg.arg1);
Log.i(TAG, "handleMessage Thread:"
+ Thread.currentThread().getName());
mainHandler.post(childThread);
// 在子线程中处理,主线程中对button的响应很快;如果这边改成主线程处理则对主线程按钮的响应就慢了
if (msg.arg1 >= 100) {
mainHandler.removeCallbacks(childThread);
}
}
}
}以上代码运行的时候为什么一定是等run方法运行完了,再等handleMessage运行结束才会响应我的button点击事件,如果是抛出消息之后就handleMessage的话,那我在handleMessage里面也抛出线程了,为什么没有就再直接去执行那个线程的run方法,而是可以就去响应之前的button点击事件了呢?这个监听器到底是怎么运行的呢?
可能因为我懂的太少,然后又理解的太浅,所以问的问题可能比较那什么哈,希望大家帮忙解释一下啦~~~
1、Android中如果创建了一个主Activity,也就是创建了一个主线程,那这个主线程有没有run方法?还有如果在Activity的onCreate方法中给button设置了监听,后面点击按钮出发Click事件,那个onCreate方法并没有再次执行,为什么还是能执行onCreate方法中的onClick方法呢?
2、还在就是如果我在主线程中创建一个Handler并且就是绑定到这个主线程的Looper上的(先不管这个有没有实际意义哈,我知道handler用在线程间消息传递才能看出他的强大哈~),具体情况请看一下下面的代码:
package com.test.handler;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;public class ChildSet extends Activity {
/** Called when the activity is first created. */
private ProgressBar myProgressbar;
private Button myButton;
private OnClickListener listener;
private Runnable childThread;
private static final String TAG = "TAG";
Myhandler mainHandler, childHandler;
private int i = 0; // private Thread t; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); myProgressbar = (ProgressBar) findViewById(R.id.progressbar_id);
myButton = (Button) findViewById(R.id.button_id); Log.i(TAG, "Main Thread:" + Thread.currentThread().getName());
// HandlerThread handlerThread = new HandlerThread("child_ron_Thread");
// handlerThread.start(); mainHandler = new Myhandler(Looper.getMainLooper());
// childHandler = new Myhandler(handlerThread.getLooper());// $$$$$$$$$$$$$ myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (i == 0) {
myProgressbar.setVisibility(ProgressBar.VISIBLE);
mainHandler.post(childThread);
i = i + 1;
}
// myProgressbar.setProgress(80);//这个可以设置的哟~~~
Log.i(TAG, "Click..." + Thread.currentThread().getName());
}
});
childThread = new Runnable() {
int persent = 0; @Override
public void run() {
// TODO Auto-generated method stub
persent += 5;
Message msg = Message.obtain();
msg.arg1 = persent;
Log.i(TAG, "Runnable Thread:"
+ Thread.currentThread().getName()); // mainHandler.sendMessage(msg);
mainHandler.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
};
} // //////////////////////////onCreate////////////////////////////
class Myhandler extends Handler {
public Myhandler(Looper looper) {
super(looper);
} public void handleMessage(Message msg) {
myProgressbar.setProgress(msg.arg1);
Log.i(TAG, "handleMessage Thread:"
+ Thread.currentThread().getName());
mainHandler.post(childThread);
// 在子线程中处理,主线程中对button的响应很快;如果这边改成主线程处理则对主线程按钮的响应就慢了
if (msg.arg1 >= 100) {
mainHandler.removeCallbacks(childThread);
}
}
}
}以上代码运行的时候为什么一定是等run方法运行完了,再等handleMessage运行结束才会响应我的button点击事件,如果是抛出消息之后就handleMessage的话,那我在handleMessage里面也抛出线程了,为什么没有就再直接去执行那个线程的run方法,而是可以就去响应之前的button点击事件了呢?这个监听器到底是怎么运行的呢?
可能因为我懂的太少,然后又理解的太浅,所以问的问题可能比较那什么哈,希望大家帮忙解释一下啦~~~
Looper.getMainLooper()看到你写的没?其实达到你说的那种效果其实很简单,不要跟主线程绑定
用如下代码就行HandlerThread hThread = new HandlerThread("test");
hThread.start();
mainHandler = new Myhandler(hThread.getLooper());
2.我不知道你和http://topic.csdn.net/u/20111027/23/ef6599ef-cba8-4726-bae5-e9fdd457c370.html
这个帖子是不是同一个发帖人。我在后面回复的比较详细了。
2.我不知道你和http://topic.csdn.net/u/20111027/23/ef6599ef-cba8-4726-bae5-e9fdd457c370.html
还有,你在那个帖子里说不需要我们主动去remove那个回调函数,那我最后点击BACK按键结束该进程的时候为什么那个handleMessage还是一直在执行呢?就算我在onDestroy函数里remove回调了,也结束了创建的子进程了也还是在一直抛消息和处理消息呀,这是为什么呢?
额……我的代码:
package com.test.handler;import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;public class MultiThreadHandler extends Activity {
private ProgressBar myProgressBar;
private Button myButton; HandlerThread barThread = new HandlerThread("ChildThread");
myHandler barHandler; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); myProgressBar = (ProgressBar) findViewById(R.id.progressbar_id);
myButton = (Button) findViewById(R.id.button_id); // HandlerThread barThread = new HandlerThread("myThread");
barThread.start();
barHandler = new myHandler(barThread.getLooper());
// myHandler barHandler = new myHandler(barThread.getLooper());
myProgressBar.setProgress(10);
Log.i("TAG", "onCreate ---> " + Thread.currentThread().getName()); Message msg = barHandler.obtainMessage();
msg.arg1 = 0;
msg.sendToTarget();
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myProgressBar.setProgress(70);
Log.i("TAG", "Click the Button...");
Message msg = barHandler.obtainMessage();
msg.arg1 = 80;
msg.sendToTarget();
barHandler.post(barThread);
// myProgressBar.setProgress(60); }
});
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
barHandler.removeCallbacks(barThread);
barThread.stop();
} class myHandler extends Handler {
public myHandler() { } public myHandler(Looper myLooper) {
super(myLooper);
} @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int ms = msg.arg1;
Log.i("TAG", "handlerMessage ---> "
+ Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myProgressBar.setProgress(50);// //////////////////////////////////////
Log.i("TAG", "The message here is " + ms);
Message msg1 = barHandler.obtainMessage();
if (msg1.arg1 < 100) {
msg1.arg1 = msg1.arg1 + 10;
msg1.sendToTarget();
// barHandler.post(barThread);
}
}
}
}
这个我必须要把模拟器都关了才有用……
1.你的myHandler实例代码是在HandlerThread线程里执行的,对于非UI线程是不允许直接操作UI上的组件的。
2.barHandler.removeCallbacks(barThread); Handler去remove一个线程是错误的用法,虽然Thread因为实现了Runnable接口,所以在语法上不会存在错误。但这个方法的作用是取消原先设置的延时回调。
3.对post和sendToTarget不理解,乱用。barHandler.post(barThread)这句没有任何意义。因为Handler的post方法作用在于执行一个runnable,你传的是一个线程(HandlerThread也是从Thread继承下来),你没有继承HandlerThread并重写run(runnable接口的接口方法),默认它是一个空方法。sendToTarget会给对应的handler添加一个消息,而你在这个消息处理里又调用一次sendToTarget,从而造成子线程死循环。
4.HandlerThread没有在任何地方看到调用其quit或者是其Looper的quit方法来退出消息循环,加上上面第3点,你的消息循环会一直处理。需要注意,即时没有消息处理也必须调用其quit方法来结束消息循环。
就说网上说的最多的一个case吧:就是在主线程中更新进度条,在另起的一个线程中给主线程发送消息,并传值给主线程,然后在主线程中接收那个消息,并取得发送过来的值,用这个值去设置进度条的进度,并且再次让那个另起的线程运行run方法并再给主线程发送更新进度条的消息,最后在进度条满了的时候就结束消息发送。
你看我这样做还行?
package com.test.handler;import com.test.handler.MultiThreadHandler.Myhandler;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;public class Final extends Activity { private Button myButton;
private ProgressBar myProgressBar;
MyHandler mainHandler, childHandler;
MyHandlerThread myHandlerThread; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myButton = (Button) findViewById(R.id.button_id);
myProgressBar = (ProgressBar) findViewById(R.id.progressbar_id);
myHandlerThread = new MyHandlerThread("Children_Thread");
myHandlerThread.start();
mainHandler = new MyHandler(getMainLooper());
childHandler = new MyHandler(myHandlerThread.getLooper()); Log.i("TAG","Thread---" + Thread.currentThread().getName() + " onCreate");
myButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("TAG","Thread---" + Thread.currentThread().getName() + " Click~~~~~~~~~~");
childHandler.post(myHandlerThread);//用子线程的Handler来post,依旧在子线程中运行run方法?????
}
});
} class MyHandlerThread extends HandlerThread { int i = 0;
public MyHandlerThread(String name) {
super(name);
// TODO Auto-generated constructor stub
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
i = i + 10;
if(i < 100) {
Log.i("TAG","Thread---" + Thread.currentThread().getName() + " i ---> " + i);
Message msg = mainHandler.obtainMessage();
msg.arg1 = i;
mainHandler.sendMessage(msg); //send到main线程的消息队列中,然后在main的handleMessage里用这个值设置进度条
}
if(i > 100) {
Log.i("TAG","Thread---" + Thread.currentThread().getName() + " removeCallbacks.......");
mainHandler.removeCallbacks(null);
}
}
} class MyHandler extends Handler { public MyHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
myProgressBar.setProgress(msg.arg1);
Log.i("TAG","Thread---" + Thread.currentThread().getName() + " The msg here ---> " + msg.arg1);
childHandler.post(myHandlerThread);
}
}
}但是运行的时候我点击按钮就报错,提示不能在一个线程里创建多个Looper…………
但是按我的理解就是在点击按钮后用子线程的Handler去post,然后执行那个run方法,接着在run方法里用主线程的mainHandler去把消息发送到主线程,再在主线程中的handleMessage方法里设置进度条,并且再次用子线程的Handler去post,从而让子线程的run方法再次执行,我这样理解对么?
再麻烦你帮我解释一下上面的问题好不好?谢谢你喽O(∩_∩)O~
真的真的谢谢你耐心的解释哟~