Nine, Android in the way of IPC (1) --- Use Bundle

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/yz_cfm/article/details/90320850

    In Android wherein three of the four components (Activity, Service, BroadcastReceiver) are supported in the data transfer Bundle the Intent. We see Intent source, carried by the Intent Bundle data putExtra () method, and then through another component getBundleExtra () method Remove Bundle data:

public Intent putExtra (String name, Bundle value)
public Bundle getBundleExtra (String name)

    Since Bundle implements Parcelable interface, so it can easily be transferred between different process:

public final class Bundle extends BaseBundle implements Cloneable, Parcelable { ... }

    Through the above description so we can know, when we started another process in a process Activity, Service, BroadcastReceiver, we can we need additional information transmitted to the remote process and sent via Intent object in the Bundle. Of course, we must be able to transfer data to be serialized, such as basic types of objects that implement the interface Parcelable achieve a special object Serializable object interface and some Android support.

Here we demonstrate a Demo, Bundle data transmission through an int and an object that implements the Serializable interface and an object that implements the interface Parcelable:

Book.java:

package com.cfm.bundletest;

public class Book implements Parcelable {
    private String mName;
    private int mPrice;

    public Book(String name, int price) {
        mName = name;
        mPrice = price;
    }

    protected Book(Parcel in) {
        mName = in.readString();
        mPrice = in.readInt();
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {

        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    public String getName() {
        return mName;
    }

    public int getPrice() {
        return mPrice;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
        dest.writeInt(mPrice);
    }
}

User.java:

package com.cfm.bundletest;

public class User implements Serializable {
    public static final long serialVersionUID = 1L;

    private String mName;
    private String mDream;

    public User(String name, String dream) {
        mName = name;
        mDream = dream;
    }

    public String getName() {
        return mName;
    }

    public String getDream() {
        return mDream;
    }
}

Tools.java:

package com.cfm.bundletest;

public class Tools{
    // 获取进程名方法
    public static String getProcessName(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();

        if (runningApps == null) {
            return null;
        }

        for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
            if (procInfo.pid == pid) {
                return procInfo.processName;
            }
        }
        return null;
    }
}

FirstActivity.java:

package com.cfm.bundletest;

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("cfmtest", "FirstActivity 所在进程名: " + Tools.getProcessName(this));

        Intent intent = new Intent(this, SecondActivity.class);
        Bundle bundle = new Bundle();
        bundle.putInt("mId", 1);
        bundle.putSerializable("mUser", new User("cfm", "open Source"));
        bundle.putParcelable("mBook", new Book("If Have a Day", 888));
        intent.putExtra("mBundle", bundle);
        startActivity(intent);
    }
}

SecondActivity.java:

package com.cfm.bundletest;

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Log.d("cfmtest", "SecondActivity 所在进程名: " + Tools.getProcessName(this));

        Intent intent = getIntent();
        Bundle bundle = intent.getBundleExtra("mBundle");
        int id = bundle.getInt("mId");
        Log.d("cfmtest", "id: " + id);
        User user = (User) bundle.getSerializable("mUser");
        Log.d("cfmtest", "userName: " + user.getName() + "userDream: " + user.getDream());
        Book book = bundle.getParcelable("mBook");
        Log.d("cfmtest", "bookName: " + book.getName() + "bookPrice: " + book.getPrice());
    }
}

AndroidManifest.xml:

...
<activity android:name=".SecondActivity"
    android:process=":remote">
</activity>
...

Print Log Information:

com.cfm.bundletest D/cfmtest: FirstActivity 所在进程名: com.cfm.bundletest
com.cfm.bundletest:remote D/cfmtest: SecondActivity 所在进程名: com.cfm.bundletest:remote
com.cfm.bundletest:remote D/cfmtest: id: 1
com.cfm.bundletest:remote D/cfmtest: userName: cfmuserDream: open Source
com.cfm.bundletest:remote D/cfmtest: bookName: If Have a DaybookPrice: 888

    By the above data we can test the transmission Bundle, assume a process of conducting a calculation A, after completion of the calculation it is to start a process of component B and passes the results to the process B, but the results do not support Bundle put in, so it can not be transmitted by intent, then if you use other ways to IPC and slightly complex, then how are we to do?

    We can through a Service component (such as IntentService) Intent to start the process in the A-B process, let B Process Service is calculated in the background, and then start the process of the target component B really want to start, because the Service is also running in the process B , the target component so you can directly get the results. So the core idea of ​​this approach is to be calculated in the original A process tasks to the background process B in Service to perform, thus successfully avoids the problem of inter-process communication, and it only took a small price .

    In general, use Bundle complete IPC, the operation is simple, the disadvantage is that the only transmission Bundle supported data types. This approach applies to communication between different processes (applications) of the four components.

Guess you like

Origin blog.csdn.net/yz_cfm/article/details/90320850