刚学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.   

    你的mainThread是阻塞的,当然就会出现你说的那种情况
    Looper.getMainLooper()看到你写的没?其实达到你说的那种效果其实很简单,不要跟主线程绑定
    用如下代码就行HandlerThread hThread = new HandlerThread("test");
    hThread.start();
    mainHandler = new Myhandler(hThread.getLooper());
      

  2.   

    1.设置onClickListener后就是给Button设置了一个监听接口。在Button类的onClick处理时会来回调你设置的接口函数。这也是android最常用的一个机制,在很多组件里都采用了这种回调的机制。
    2.我不知道你和http://topic.csdn.net/u/20111027/23/ef6599ef-cba8-4726-bae5-e9fdd457c370.html
    这个帖子是不是同一个发帖人。我在后面回复的比较详细了。
      

  3.   

    1.设置onClickListener后就是给Button设置了一个监听接口。在Button类的onClick处理时会来回调你设置的接口函数。这也是android最常用的一个机制,在很多组件里都采用了这种回调的机制。
    2.我不知道你和http://topic.csdn.net/u/20111027/23/ef6599ef-cba8-4726-bae5-e9fdd457c370.html
      

  4.   

    先申明一下哈,我不是你说的那个同一个发帖人的人啦~
    还有,你在那个帖子里说不需要我们主动去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);
     }
    }
    }
    }
    这个我必须要把模拟器都关了才有用……
      

  5.   

    你的代码还是有多处的问题。
    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方法来结束消息循环。
      

  6.   

    回调函数是android的很常见的一种事件处理机制,是一种由系统来回调你指定的函数的做法。按钮的监听即是如此,你设置一个监听接口,该接口有个方法,你必须实现这个接口方法,然后指定按钮的Click监听为该接口对象。当该按钮被Click时候,系统收到Click事件后发现其设置了监听接口,于是来回调这个接口的onClick方法
      

  7.   

    真的非常非常感谢你的耐心呀~最后一个问题哈~~
    就说网上说的最多的一个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~
      

  8.   

    谢谢你了哈,我刚刚弄懂了,刚刚回帖上面的那个其实只要把那个自定义的线程类换成Runnable接口就可以了,因为post的是Runnable对象呢,然后那个什么时候用mainHandler,什么时候用childHandler就像上个回帖上面说的那样了。
    真的真的谢谢你耐心的解释哟~