数据传递

概览:Intent SharedPreferences Settings SystemProperties Handler Message IBinder

Intent

适用于startActivity、startService或sendBroadcast时传递数据。
单向传递。

Intent传递简单数据
//存数据
//一次传一个
Intent intent = new Intent();
//value可以是boolean\byte\char\short\int\long\float\double\String\数组\Bundle
intent.putExtra(name,value);
mContext.startActivity(intent);
//一次传多个
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt(key,value);
bundle.putString(key,value);
intent.putExtra(bundle);
mContext.startActivity(intent);
//取数据
Intent intent = getIntent();
intent.getBooleanExtra(name, def);
intent.getByteExtra(name, def);
intent.getCharExtra(name, def);
intent.getShortExtra(name, def);
intent.getIntExtra(name, def);
intent.getLongExtra(name, def);
intent.getFloatExtra(name, def);
intent.getDoubleExtra(name, def);
intent.getStringExtra(name, def);
intent.getStringArrayExtra(name);
Bundle bundle = intent.getBundleExtra(name);
bundle.getInt(key);
bundle.getString(key);
Intent传递集合
//List<String>
intent.putStringArrayListExtra(name, value);
intent.getStringArrayListExtra(name);
//List<Integer>
intent.putIntegerArrayListExtra(name, value);
intent.getIntegerArrayListExtra(name);
//List<Object>
intent.putExtras(key, (Serializable)list);
(List<Object>) intent.getSerializable(key);
Intent传递对象
//将对象转换为Json字符串
intent.putExtra("book",new Gson().toJson(book));
String bookJson=getIntent().getStringExtra("book");
Book book=new Gson().fromJson(bookJson,Book.class);
//使用Serializable,Parcelable序列化对象
intent.putExtra(String name, Serializable value);
intent.getSerializableExtra(name);
//bitmap默认实现Parcelable接口,直接传递即可
intent.putExtra(String name, Parcelable value);
(Bitmap) intent.getParcelableExtra(name);

SharedPreferences数据传递

适用于应用内存储数据,应用提供SharedPreferences来传递数据

import android.content.Context;
import android.content.SharedPreferences;

private SharedPreferences mPrefs;
private SharedPreferences.Editor mEditor;

mPrefs = getPrefs(mContext);
//存数据
mEditor = mSharedPreferences .edit();
mEditor.putBoolean(key, true);
mEditor.putInt(key,value);
mEditor.putString(key,value);
mEditor.commit();
//取数据
mPrefs.getBoolean(key,defaulvalue);
mPrefs.getInt(key,defaulvalue);
mPrefs.getString(key,defaulvalue);

//创建mPrefs,保存在/data/data/[package name]/shared_prefs目录
public static SharedPreferences getPrefs(Context context) {
    return context.getApplicationContext()
          .getSharedPreferences("com.android.launcher3.prefs",Context.MODE_PRIVATE);
}

//创建mPrefs,保存在/data/system_de/userid/目录
public static SharedPreferences getPrefs(Context context) {
    final File prefsFile = new File(
          Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), "prefs.xml");
    return context.createDeviceProtectedStorageContext()
          .getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
}

Settings数据传递

适用于系统跨进程数据传递,全局存储数据,可以监听数据变化。
注意没有putBoolean()和getBoolean()方法。

import android.provider.Settings;
//存数据
Settings.Global.putString(mContext.getContentResolver(), key, value);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.XXX, 1);
Settings.System.putInt(mContext.getContentResolver(), Settings.System.XXX, 1);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.XXX, 1);
//取数据
Settings.Global.getString(mContext.getContentResolver(), key, defaultvalue);
Settings.Global.getLong(mContext.getContentResolver(),Settings.Global.XXX, 0) ;
Settings.Global.getFloat(mContext.getContentResolver(),Settings.Global.XXX, 0.1) ;
Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.XXX, 0) ;
Settings.System.getInt(mContext.getContentResolver(),Settings.System.XXX, 0) ;
Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.XXX, 0) ;

SystemProperties数据传递

适用于系统跨进程数据传递,全局存取数据,不能够监听数据变化。
注意属性name需以persist.或sys.开头。

import android.os.SystemProperties;
//存数据
SystemProperties.set(name, value);
//取数据
SystemProperties.getInt(name, def);
SystemProperties.getLong(name, def);
SystemProperties.getBoolean(name, false);

非系统应用可以反射读取属性

import android.text.TextUtils;
import java.lang.reflect.Method;

public static String getSystemProperty(String name, String def) {
    try {
        Class clazz = Class.forName("android.os.SystemProperties");
        Method getter = clazz.getDeclaredMethod("get", String.class);
        String value = (String) getter.invoke(null, name);
        if (!TextUtils.isEmpty(value)) {
            return value;
        }
    } catch (Exception e) {
        Log.d(TAG, "Unable to read system properties");
    }
    return def;
}

Handler Message IBinder数据传递

适用于应用跨进程数据传递。客户端发送事件请求,并接收服务端返回的数据。
互相传递。

package com.xxx.service.helper;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class XxxServiceHelper {
    private static final String TAG = "XxxServiceHelper";

    private static final String SERVICE_PACKNAME = "com.android.systemui";
    private static final String SERVICE_CLASSNAME = "com.xxx.XxxService";
    private static final long DELAY_TIME = 5000;
    public static final int DEVICE_INFO_EVENT = 1;

    private final Context mContext;
    private int mEvent;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private boolean mBound = false;

    public MagazineServiceHelper(Context context) {
        mContext = context;
    }

    public void request(int event){
        Log.i(TAG,"luncher event:"+event);
        mEvent = event;
        final Intent serviceIntent = new Intent();
        ComponentName serviceComponent = new ComponentName(SERVICE_PACKNAME, SERVICE_CLASSNAME);
        serviceIntent.setComponent(serviceComponent);
        if(mContext.bindService(serviceIntent,connection,Context.BIND_AUTO_CREATE)){
            mHandler.postDelayed(mTimeoutRunnable,DELAY_TIME);
        }
    }

    final Runnable mTimeoutRunnable = new Runnable() {
        @Override public void run() {
            Log.i(TAG,"mTimeoutRunnable mBound:"+mBound);
            if(mBound) {
                mContext.unbindService(connection);
            }
        }
    };

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i(TAG,"onServiceConnected");
            mBound = true;
            Messenger service = new Messenger(iBinder);
            //发送事件到服务端
            Message msg = Message.obtain(null,mEvent);
            Handler handler = new Handler(mHandler.getLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    Log.i(TAG,"received service msg:"+msg.what);
                    if(DEVICE_INFO_EVENT == msg.what){
                        //接收service数据
                        Bundle bundle = msg.getData();
                        String sn = bundle.getString("SN");
                        String imei = bundle.getString("IMEI");
                        Log.i(TAG,"received sn:"+sn+" imei:"+imei);
                    }
                    mContext.unbindService(connection);
                    mHandler.removeCallbacks(mTimeoutRunnable);
                }
            };
            msg.replyTo = new Messenger(handler);
            try {
                service.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i(TAG,"onServiceDisconnected");
            mBound = false;
            mHandler.removeCallbacks(mTimeoutRunnable);
        }
    };
}

服务端接收事件请求,并传递数据给客户端

package com.xxx.xxx;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class XxxService extends Service {

    private static final String TAG = "XxxService ";
    private static final int DEVICE_INFO_EVENT = 1;
    private Messenger mReplyMesenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new Messenger(mHandler).getBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();   
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private Handler mHandler = new Handler(Looper.myLooper()){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            //获取客户端事件
            Log.i(TAG,"handleMessage: " + msg.what);
            mReplyMesenger = msg.replyTo;
            if(DEVICE_INFO_EVENT == msg.what){
                Bundle bundle = new Bundle();
                String sn = readSn();
                String imei = readImei();
                Log.i(TAG,"send sn: " + sn +" imei:"+imei);
                bundle.putString("SN",sn);
                bundle.putString("IMEI",imei);
                sendMsg(DEVICE_INFO_EVENT,bundle);
            }
        }
    };
    
    private String readSn(){
        return "1234567890ABCDEF";
    }

    private String readImei(){
        return "123456";
    }

    //发送数据给客户端
    private void sendMsg(int what,Bundle bundle){
        if (mReplyMesenger != null) {
            try {
                Message msg = Message.obtain(null, what);
                msg.setData(bundle);
                mReplyMesenger.send(msg);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。