天天看點

Android學習之異步任務Handler

今天來講下Handler,為什麼要使用Handler呢?主要有兩個原因:

一是線程安全問題,假如同時有兩個線程對一個UI控件進行調整,那麼控件自然就沒法正常的工作。而Handler永遠都是在UI主線程,這就意味着對一個控件的修改永遠隻會有一個線程,不會存在多個線程同時修改一個控件。二是友善統一管理,通過Handler可以統一進行對UI的管理,因為Handler采用消息處理的機制。就是另一個線程發送一個編号給消息所在的線程,那麼該線程的消息處理程式就會收到該消息并進行處理,而消息采用int類型,是以int能夠表示多少種數字就以為着有多少消息可以給你使用。

下面使用一個發送不同的消息來進入不同的Activity的Demo來看看Handler的使用,如下:

常量類,個人習慣

/**
 * 常量
 *
 * @author yuzhentao
 */
public class Constants {

    public static final String SP_NAME = "sp_name";
    public static final String SP_STATE = "sp_state";
    public static final int STATE_FIRST = 1001;
    public static final int STATE_SIGN_IN = 1002;
    public static final int STATE_NOT_SIGN_IN = 1003;

}      

SP工具,這樣友善使用

/**
 * SharedPreferences工具
 *
 * @author yuzhentao
 */
public class SharedPreferencesUtil {

    /**
     * 設定SharedPreferences
     *
     * @param context:Context
     * @param key:鍵
     * @param value:值
     */
    public static void setSP(Context context, String key, int value) {
        Editor et = context.getSharedPreferences(Constants.SP_NAME, Context.MODE_PRIVATE).edit();
        et.putInt(key, value);
        et.apply();
    }

    /**
     * 擷取SharedPreferences
     *
     * @param context:Context
     * @param key:鍵
     * @param defaultValue:值
     * @return 值
     */
    public static int getSP(Context context, String key, int defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(Constants.SP_NAME, Context.MODE_PRIVATE);
        return sp.getInt(key, defaultValue);
    }

}      

接下來是幾個Activity

/**
 * 引導界面
 *
 * @author yuzhentao
 */
public class LogoActivity extends Activity {

    private static final int GO_GUIDE = 1;
    private static final int GO_SIGN_IN = 2;
    private static final int GO_MAIN = 3;

    private static final int DELAY_TIME = 1000;

    private Context context;

    private LogoHandler logoHandler = new LogoHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_logo);
        context = this;
        initView();
    }

    private void initView() {
        int state = SharedPreferencesUtil.getSP(context, Constants.SP_STATE, Constants.STATE_FIRST);
        if (state == Constants.STATE_FIRST) {
            logoHandler.sendEmptyMessageDelayed(GO_GUIDE, DELAY_TIME);
        } else {
            if (state == Constants.STATE_NOT_SIGN_IN) {
                logoHandler.sendEmptyMessageDelayed(GO_SIGN_IN, DELAY_TIME);
            } else if (state == Constants.STATE_SIGN_IN){
                logoHandler.sendEmptyMessageDelayed(GO_MAIN, DELAY_TIME);
            }
        }
    }

    /**
     * 開啟Activity
     *
     * @param activity:Activity
     * @param cls:Class<?>
     */
    private static void startActivity(Activity activity, Class<?> cls) {
        activity.startActivity(new Intent(activity, cls));
        activity.finish();
    }

    /**
     * LogoHandler
     */
    private static class LogoHandler extends Handler {

        private final WeakReference<LogoActivity> logoActivityWeakReference;

        LogoHandler(LogoActivity activity) {
            logoActivityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            LogoActivity activity = logoActivityWeakReference.get();
            switch (msg.what) {
                case GO_GUIDE:
                    startActivity(activity, GuideActivity.class);
                    break;
                case GO_SIGN_IN:
                    startActivity(activity, SignInActivity.class);
                    break;
                case GO_MAIN:
                    startActivity(activity, MainActivity.class);
                    break;
            }
        }

    }

}      
/**
 * 引導界面
 *
 * @author yuzhentao
 */
public class GuideActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guide);
        findViewById(R.id.button_activity_guide).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(GuideActivity.this, SignInActivity.class));
            }
        });
    }

}      
/**
 * 登入界面
 *
 * @author yuzhentao
 */
public class SignInActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_in);
        SharedPreferencesUtil.setSP(this, Constants.SP_STATE, Constants.STATE_NOT_SIGN_IN);
        findViewById(R.id.button_activity_sign_in).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferencesUtil.setSP(SignInActivity.this, Constants.SP_STATE, Constants.STATE_SIGN_IN);
                startActivity(new Intent(SignInActivity.this, MainActivity.class));
            }
        });
    }

}      
/**
 * 主界面
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SharedPreferencesUtil.setSP(this, Constants.SP_STATE, Constants.STATE_NOT_SIGN_IN);
    }

}      

每個Activity中通過使用SharedPreferences來給每個Activity設定不同的标記,然後第一個Activity即LogoActivity來擷取SP的值來選擇發送不同的消息到LogoHandler的handleMessage()中進行處理,handleMessage()顧名思義是用來處理消息的,根據不同的message來啟動不同的Activity。

這裡注意Handler必須為static的,然後使用弱引用的方式來傳遞Activity,不然肯定會報@SuppressLint("HandlerLeak")警告,解決方式就是采用這種寫法。

最後是效果圖:

Android學習之異步任務Handler
Android學習之異步任務Handler
Android學習之異步任務Handler
Android學習之異步任務Handler

Demo位址:http://download.csdn.net/detail/qq_23940659/9467052