intent不宜传送大量数据

Intent中可以存放bundle类型数据,而bundle数据可以用来保存键值对数据,还可以保存数组,在进程通信中来传数据很方便,但是需要注意,intent的传送的本质是binder方式,这就决定了不能用来传送大数据量的数据,不然会出问题。
Binder适合少量的数据传送,以前做过一个试验,在sensorManager里的事件处理中,来进行binder调用,1秒30次的调用,基本不会有卡顿。

关于intent的传送,以bindService的调用为例。sendBroadcast的本质也一样。

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	bindService(new Intent("com.sunday.aidl.IMathService"), 
			serviceConnection, BIND_AUTO_CREATE);
	
	
	Button aButton = (Button)findViewById(R.id.button1);
	aButton.setOnClickListener(this);
}

public class ContextWrapper extends Context {
Context mBase;

public ContextWrapper(Context base) {
    mBase = base;
}

public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    return mBase.bindService(service, conn, flags);
}

ContextImpl.java
// bindService
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}

// bindServiceCommon
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) {
    IServiceConnection sd;
    ...

//包装ServiceConnection
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);

    ...

    int res = ActivityManagerNative.getDefault().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());

    ...

}

这里是通过binder和AMS进行通信,一次binder调用
ActivityManagerNative.java
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService(“activity”);
if (false) {
Log.v(“ActivityManager”, "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v(“ActivityManager”, "default service = " + am);
}
return am;
}
};
}

static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

    return new ActivityManagerProxy(obj);
}

public abstract class Singleton {
private T mInstance;

protected abstract T create();

public final T get() {
    synchronized (this) {
        if (mInstance == null) {
            mInstance = create();
        }
        return mInstance;
    }
}

}

即包装ServiceManager.getService(“activity”);
继续查看bindServiceCommon方法
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException(“connection is null”);
}
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else {
throw new RuntimeException(“Not supported in system context”);
}
validateServiceIntent(service);
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess(this);
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());

这个sd是怎么来的呢
ServiceDispatcher用来包装ServiceConnection
创建binder实体对象,用来响应回调
LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
sd = map.get©;
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}

    ServiceDispatcher(ServiceConnection conn,
            Context context, Handler activityThread, int flags) {
        mIServiceConnection = new InnerConnection(this);
        mConnection = conn;
        mContext = context;
        mActivityThread = activityThread;
        mLocation = new ServiceConnectionLeaked(null);
        mLocation.fillInStackTrace();
        mFlags = flags;
    }

InnerConnection用来进行binder通信
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

        InnerConnection(LoadedApk.ServiceDispatcher sd) {
            mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
        }

        public void connected(ComponentName name, IBinder service) throws RemoteException {
            LoadedApk.ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
                sd.connected(name, service);
            }
        }
    }

AMS端作为Proxy进行调用connected方法

猜你喜欢

转载自blog.csdn.net/aaajj/article/details/111456470