La intención no debe transmitir grandes cantidades de datos

Los datos del tipo de paquete se pueden almacenar en Intent, y los datos del paquete se pueden usar para almacenar datos de pares clave-valor, y también pueden almacenar matrices. Es muy conveniente transferir datos en la comunicación del proceso, pero debe tenerse en cuenta que la esencia de intención de transferencia es el método de enlace Se determina que no se puede utilizar para transmitir grandes cantidades de datos, de lo contrario se producirán problemas.
Binder es adecuado para una pequeña cantidad de transmisión de datos. He realizado un experimento antes. En el procesamiento de eventos en el sensorManager, se llama al binder. La llamada es 30 veces por segundo, y básicamente no habrá retraso.

Con respecto a la transferencia de intenciones, tome la llamada de bindService como ejemplo. La esencia de sendBroadcast es la misma.

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);
}

ContextWrapper de clase pública extiende 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 (servicio, conexión, banderas, 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());

    ...

}

Aquí está la comunicación a través de Binder y AMS, un Binder llama
ActivityManagerNative.java
private static final Singleton gDefault = new Singleton () { protected IActivityManager create () { IBinder b = ServiceManager.getService ("activity"); if (false) { Log .v ("ActivityManager", " enlazador de servicios predeterminado =" + b); } IActivityManager am = asInterface (b); if (false) { Log.v ("ActivityManager", "servicio predeterminado =" + am); } return soy; } }; }












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);
}

clase pública abstracta Singleton { T mInstance privado;

protected abstract T create();

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

}

即 包装 ServiceManager.getService ("actividad");
继续 查看 bindServiceCommon 方法
private boolean bindServiceCommon (Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) { IServiceConnection sd; if (conn == null) { lanzar una nueva IllegalArgumentException ("la conexión es nula"); } if (mPackageInfo! = null) { sd = mPackageInfo.getServiceDispatcher (conn, getOuterContext (), handler, flags); } else { lanzar nueva RuntimeException ("No admitido en el contexto del sistema"); } validateServiceIntent (servicio); intente { 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 (esto); int res = ActivityManagerNative.getDefault (). bindService ( mMainThread.getApplicationThread (), getActivityToken (), service, service.resolveTypeIfNeeded (getContentResolver ()), sd, flags, getOpPackageName (), user.getIdentifier ());






¿De dónde proviene este sd?
ServiceDispatcher se usa para envolver ServiceConnection para
crear objetos de entidad vinculante, que se usan para responder a la devolución de llamada
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 (contexto, mapa); }












map.put (c, sd);
} else { sd.validate (contexto, controlador); } 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 通信
clase estática privada InnerConnection extiende 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);
            }
        }
    }

El lado AMS actúa como un proxy para llamar al método conectado

Supongo que te gusta

Origin blog.csdn.net/aaajj/article/details/111456470
Recomendado
Clasificación