編輯:關於Android編程
Android中Handler的原理
一.Handler的原理:
1.Handler、Looper、MessageQueue之間的關系。
(1).Handler類:向MessageQueue消息隊列中發送消息,接收Looper返回來的消息並處理。
(2).Looper類: 存儲消息隊列的容器。負責接收Handler發送的消息,並直接把消息回傳給Handler自己。
(3).MessageQueue類:存儲消息。
2.關系:
(1).創建Handler對象的時候,它就會綁定到默認的線程(UI線程)中,這個線程中就會有一個消息隊列。
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Log.d(TAG, 主線程 Thread UI: + Thread.currentThread().getId());
mView.setText(111);
};
};
(2).如果是新開啟一個子線程,在該線程中操作Handler的時候,就要自己創建一個Looper對象,從而找到相應的消息隊列。也就是說Handle和Looper是相互關聯的。
package com.chengdong.su.handlerdemo;
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Build;
/**
*
* @author scd
*
*/
public class ThridActivity extends Activity {
private String TAG = getClass().getSimpleName();
private TextView mView;
private MyThread mThread;
/**
* 創建一個默認的Handler
*/
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Log.d(TAG, -------UI Thread: + Thread.currentThread().getId());
mView.setText(你好);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
mThread = new MyThread();
mThread.start();
try {
mThread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 子線程
mThread.myHandler.sendEmptyMessage(0);
// 主線程
mHandler.sendEmptyMessage(1);
}
private void init() {
mView = (TextView) findViewById(R.id.textView1);
}
/**
* 自定義的Thread
*
* @author scd
*
*/
public class MyThread extends Thread {
public Handler myHandler;
@Override
public void run() {
Looper.prepare();
myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, ------>Thread:
+ Thread.currentThread().getId());
System.out.println(---子線程----);
}
};
// 循環處理消息
Looper.loop();
}
}
}
但是使用以上的方式會出現多線程並發導致的空指針問題,為了避免這個問題,谷歌給我們封裝了一個很好用的類:HandlerThread類。
3.HandlerThread類:
(1).解決多線程並發導致的空指針問題。
HandlerThread的使用代碼如下:
package com.chengdong.su.handlerdemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
/**
*
* @author scd
*
*/
public class FourActivity extends Activity {
private String TAG = getClass().getSimpleName();
private String mName = HandlerThread;
private HandlerThread mThread;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 封裝類
mThread = new HandlerThread(mName);
// 開啟線程
mThread.start();
// 方式一:Handler是在子線程
mHandler = new Handler(mThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, ---子線程----HandlerThread :
+ Thread.currentThread().getId());
}
};
// 方式二:Handler是在主線程
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, ---主線程 UI----HandlerThread :
+ Thread.currentThread().getId());
}
};
mHandler.sendEmptyMessage(0);
Log.d(TAG, ---主線程----UIThread : + Thread.currentThread().getId());
}
}
注:方式一中的mHandler是運行在子線程中的,可以在該Handler中處理耗時的異步任務,發送消息,處理消息等。
(2).Android中主線程和子線程之間的通信:
A:子線程發送給主線程消息:讓主線程更新UI界面
B:主線程發送給子線程消息:讓子線程做相應的邏輯處理。
代碼如下:
package com.chengdong.su.handlerdemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* 主線程和子線程之間進行互相的發送消息,進行通信
*
* @author scd
*
*/
public class FiveActivity extends Activity implements OnClickListener {
private String TAG = getClass().getSimpleName();
private String mName = HandlerThread;
// 初始化主線程的Handler
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Message message = new Message();
// 主線程發送給子線程消息
mThreadHandler.sendMessageDelayed(message, 1000);
Log.d(TAG, -------->主線程發送給子線程消息);
};
};
// 子線程對象
private HandlerThread mThread;
// 子線程的Handler
private Handler mThreadHandler;
private Button mButton1;
private Button mButton2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* init the View
*/
private void init() {
mButton1 = (Button) findViewById(R.id.button1);
mButton2 = (Button) findViewById(R.id.button2);
mButton1.setOnClickListener(this);
mButton2.setOnClickListener(this);
// 初始化子線程的Handler
mThread = new HandlerThread(mName);
mThread.start();
// 初始化子線程中的Handler
mThreadHandler = new Handler(mThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
Message message = new Message();
mHandler.sendMessageDelayed(message, 1000);
Log.d(TAG, -------->子線程發送給主線程消息);
}
};
Log.d(TAG, ------->init主線程);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1: {
// 主線程發送消息
mHandler.sendEmptyMessage(0);
break;
}
case R.id.button2: {
// 取消消息
mHandler.removeMessages(0);
break;
}
default:
break;
}
}
}
一、RxJava概念RxJava官方定義一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫。用一個詞概括:異步,也就是說RxJava也可以理解為一
Android:使用AppCompatAutoCompleteTextView:我們先看看實現的效果吧,也就是我們俗話說的自動提示功能。這裡我實現了點擊AppCompat
源碼與示例apkhttps://github.com/dengyuhan/android-adapters 快速開始Android Studio - 在buil
大家都知道,android studio 有一個功能就是使用第三方jar的時候在build.gradle中直接 compile 'com.android.supp