现在的位置: 首页 > 综合 > 正文

android in practice_Share data by sharing Context

2017年12月24日 ⁄ 综合 ⁄ 共 2693字 ⁄ 字号 评论关闭

You have two or more applications that are closely related and depend on each other. You want them to share private resources such as files or code that must not be visible

to other applications, but due to Android’s strict sandboxing rules, they’re not allowed to.

We said before that this doesn’t work for two reasons:
1 Different applications run in different Linux system processes.
2 Different applications are mapped to different Linux user IDs.
The solution is to let these applications share the same application process and the same user ID.

App1 is the data provider

App1.java implements toString() and writes a shared preference file:

public class App1 extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //open share preference file
        SharedPreferences prefs=this.getSharedPreferences("app1prefs",MODE_PRIVATE);
        String value="Hello from App1 preference file!";
        //write value to file
        prefs.edit().putString("shared_value", value).commit();
    }
    
    public String toString(){
		return "Hello from App1 toString()!";
    	
    }
    
}

1 We somehow must get hold of the resources bundled with App1—calling get-Resources in App2 will only return its own!
2 We must somehow get the right to access these resources. Even if we find a way to reference them, they still belong to App1, not App2!

createPackageContext method defined on the android.content.Context class. This method allows us to create a handle to a context object that represents an application package.

Using the context object returned by that method, we can then get a reference to its class loader and load classes from that application and instantiate them. We can also use that context object to get a handle to its resource package or shared preferences.

two attributes we’ve set in the manifest files of both applications: android:process and android:sharedUserId.

public class App2 extends Activity {
	private Context app1;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        try {
        	app1=this.createPackageContext("example.sharedprocessapp1", this.CONTEXT_INCLUDE_CODE);
        	Class<?> app1ActivityCls=app1.getClassLoader().loadClass("example.sharedprocessapp1.App1");
        	Object app1Activity=app1ActivityCls.newInstance();
        	Toast.makeText(this, app1Activity.toString(), Toast.LENGTH_LONG);
         } catch (Exception e) {
            e.printStackTrace();
            return;
         }

         SharedPreferences prefs=app1.getSharedPreferences("app1prefs", MODE_PRIVATE);
         TextView view=(TextView)findViewById(R.id.hello);
         String shared=prefs.getString("shared_value", null);
         if(shared==null){
        	 view.setText("failed to share");
         }else{
        	 view.setText(shared);
         }
    }
}

For both applications, we need to set these to identical values:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="..."
android:sharedUserId="com.manning.aip">
<application android:process="com.manning.aip">
<activity … />
</application>
</manifest>

抱歉!评论已关闭.