zoukankan      html  css  js  c++  java
  • Android跨应用间的数据传输

    在有些项目中,会有多个应用出现,这样应用间的数据传输就成了必然。那应用间的数据传输要怎么实现呢?我们知道,在跨Activity之间的数据传输可以通过Bundle和Intent结合来实现,那应用间的数据传输是否也可以使用这种方式呢?答案是可以的!

    在使用Bundle来传输数据时,又有多种途径,比如直接数据传输、序列化数据传输、打包数据传输等。下面是从TransDataA应用传输到TransDataB应用的效果图。





    在直接传输数据时,我们传输的是图片数据,序列化传输和打包传输时传输的是相应的结构信息,下面是实现的代码:

    TransDataA项目的MainActivity.java

    package com.example.transdataa;
    
    import com.example.data.DirectData;
    import com.example.data.SerialData;
    import com.example.data.ParcelData;
    
    import com.kitsp.contentsp.IntentSp;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class MainActivity extends Activity {
    
    	private Button _directTrans_button = null;
    	private Button _serialTrans_button = null;
    	private Button _pracelTrans_button = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		Init();
    	}
    
    	private void Init() {
    		FetchUIControls();
    		BindingEvents();
    	}
    
    	private void FetchUIControls() {
    		_directTrans_button = (Button) findViewById(R.id.activity_main_directTrans);
    		_serialTrans_button = (Button) findViewById(R.id.activity_main_serialTrans);
    		_pracelTrans_button = (Button) findViewById(R.id.activity_main_ParcelTrans);
    	}
    
    	private void BindingEvents() {
    		if(_directTrans_button!=null)
    		{
    			_directTrans_button.setOnClickListener(new OnClickListenerEx());
    		}
    		
    		if (_serialTrans_button != null) {
    			_serialTrans_button.setOnClickListener(new OnClickListenerEx());
    		}
    
    		if (_pracelTrans_button != null) {
    			_pracelTrans_button.setOnClickListener(new OnClickListenerEx());
    		}
    	}
    
    	private class OnClickListenerEx implements OnClickListener {
    
    		@Override
    		public void onClick(View v) {
    			Bundle bundle = null;	
    			switch (v.getId()) {
    			case R.id.activity_main_directTrans:
    			{
    				bundle=DirectGenerateData();
    				break;
    			}
    			case R.id.activity_main_serialTrans: {
    				bundle = SerializeData();
    				break;
    			}
    			case R.id.activity_main_ParcelTrans: {
    				bundle = ParcelableData();
    				break;
    			}
    			default: {
    				break;
    			}
    			}
    			TransData(bundle);
    		}		
    	
    		private Bundle DirectGenerateData()
    		{
    			Bundle bundle = new Bundle();
    			Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.test);
    			bundle.putParcelable(DirectData.KEY, bitmap);
    			return bundle;
    		}
    		
    		private Bundle SerializeData() {
    			SerialData serialData = new SerialData();
    			serialData.SetSerialNo("123456789");
    			serialData.SetWeight(180.82);
    			Bundle bundle = new Bundle();
    			bundle.putSerializable(SerialData.KEY, serialData);
    			return bundle;
    		}
    
    		private Bundle ParcelableData() {
    			ParcelData parcelData = new ParcelData();
    			parcelData.SetAccount("Test");
    			parcelData.SetPassword("ABCDEFG");
    			parcelData.SetAge(25);
    			Bundle bundle = new Bundle();
    			bundle.putParcelable(ParcelData.KEY, parcelData);
    			return bundle;
    		}
    
    		private void TransData(Bundle bundle) {
    			if (bundle == null) {
    				return;
    			}
    			Intent intent = new Intent();
    			ComponentName cn = new ComponentName("com.example.transdatab",
    					"com.example.transdatab.MainActivity");
    			if (cn != null) {
    				intent.setComponent(cn);
    				intent.putExtras(bundle);
    				startActivity(intent);
    			}
    
    		}
    	}
    }
    
    注:

    1、数据都是以Bundle的形式添加到Intent中的。一定要记得在Intent中putExtras(bundle)。这是将数据添加到Intent的必须步骤,有时可能会遗忘。

    2、在跨应用时,使用Intent来启动另一个应用。这里采用ComponentName的形式来启动另一个应用。

    3、在使用Intent传输数据时有上限的限制,不然会导致应用卡死或黑屏。具体上限是多少,网上有很多说法,有说40kb的、有说100kb的,有说1M的,我实际测试的结果是200kb左右。我的结论是可能与具体的设备有关。

    TransDataB项目的MainActivity.java

    package com.example.transdatab;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.widget.TextView;
    
    import com.example.data.DirectData;
    import com.example.data.SerialData;
    import com.example.data.ParcelData;
    
    public class MainActivity extends Activity {
    
    	private SerialData _serialData = null;
    	private ParcelData _parcelData = null;
    	private Bitmap _bitmap=null;
    	private TextView _info_textView = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		Init();
    	}
    
    	private void Init() {
    		FetchUIControls();
    		InitParams();
    		InitUI();
    	}
    
    	private void InitParams() {
    		try {
    			Intent intent = getIntent();
    			if (intent == null) {
    				_info_textView.setText("Intent is null");
    				return;
    			}
    
    			if(intent.hasExtra(DirectData.KEY))
    			{
    				_bitmap=intent.getParcelableExtra(DirectData.KEY);
    			}
    			
    			if (intent.hasExtra(SerialData.KEY)) {
    				_serialData = (SerialData) intent
    						.getSerializableExtra(SerialData.KEY);
    				_info_textView.setText("MachineData");
    			}
    
    			if (intent.hasExtra(ParcelData.KEY)) {
    				_info_textView.setText("RegisterData");
    				_parcelData = (ParcelData) intent
    						.getParcelableExtra(ParcelData.KEY);
    			}
    
    		} catch (Exception e) {
    			_info_textView.setText("Exception");
    		}
    	}
    
    	private void FetchUIControls() {
    		_info_textView = (TextView) findViewById(R.id.activity_main_info);
    	}
    
    	private void InitUI() {
    
    		if (_info_textView == null) {
    
    			return;
    		}
    				
    		String info = "";
    
    		if(_bitmap!=null)
    		{
    			BitmapDrawable bitmapDrawble= new BitmapDrawable(MainActivity.this.getResources(), _bitmap); 
    			bitmapDrawble.setBounds(0, 0, _bitmap.getWidth(),_bitmap.getHeight());
    			_info_textView.setCompoundDrawables(null, bitmapDrawble, null, null);
    		}
    		
    		if (_serialData != null) {
    			info = "SerialData
    SerialNo=" + _serialData.GetSerialNo() + "
    Weight="
    					+ _serialData.GetWeight() + "
    ";
    		}
    
    		if (_parcelData != null) {
    			info = "ParcelData
    Account=" + _parcelData.GetAccount() + "
    " + "Password="
    					+ _parcelData.GetPassword() + "
    " + "Age="
    					+ _parcelData.GetAge() + "
    ";
    		}
    		_info_textView.setText(info);
    	}
    }
    
    注:

    1、在接收数据的一端,先获取Intent,再判断是否有相应的KEY,然后再解开数据。

    2、在获取直接传输过来的数据时,采用intent.getParcelableExtra来获取数据。

    在TransDataA和TransDataB中传输序列化和打包的数据时,一定要用同样的KEY和同样的类,不然数据会解不开。这里,他们共用的是TransData项目中的类,下面是代码。

    TransData项目的DirectData.java

    package com.example.data;
    
    public class DirectData {
    	public final static String KEY="{56896229-BFCD-4630-B1EF-4D8FA6CA90FE}";
    }
    
    注:直接传输数据,只需要一个唯一的KEY就可能 了。KEY采用GUID以确保唯一性,也可以自己命名,只要能确保唯一性就可以。

    TransData项目的SerialData.java

    package com.example.data;
    
    import java.io.Serializable;
    
    public class SerialData implements Serializable {
    
    	public static final String KEY="{1D7D9EF2-06F6-4A55-9DF6-293471209D15}";
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1464294135398038125L;
    
    	private String _serialNo="";
    	private double _weight_kg=0;
    	
    	public void SetSerialNo(String serialNo)
    	{
    		_serialNo=serialNo;
    	}
    	
    	public String GetSerialNo()
    	{
    		return _serialNo;
    	}
    	
    	public void SetWeight(double weight_kg)
    	{
    		_weight_kg=weight_kg;
    	}
    	
    	public double GetWeight()
    	{
    		return _weight_kg;
    	}
    	
    }
    
    注:

    1、需实现Serializable。

    2、每一个变量都必须要有对应的Set和Get方法。

    TransData项目的ParcelData.java

    package com.example.data;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class ParcelData implements Parcelable {
    
    	public final static String KEY="{00D2DF54-B448-415F-AB7C-E0C6B6D3E608}";
    	
    	private String _account="";
    	private String _password="";
    	private int _age=0;
    	
    	public void SetAccount(String account)
    	{
    		_account=account;
    	}
    	
    	public String GetAccount()
    	{
    		return _account;
    	}
    	
    	public void SetPassword(String password)
    	{
    		_password=password;
    	}
    	
    	public String GetPassword()
    	{
    		return _password;
    	}
    	
    	public void SetAge(int age)
    	{
    		_age=age;
    	}
    	
    	public int GetAge()
    	{
    		return _age;
    	}
    	
    	
    	@Override
    	public int describeContents() {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    	@Override
    	public void writeToParcel(Parcel dest, int flags) {
    		// TODO Auto-generated method stub
    		dest.writeString(_account);
    		dest.writeString(_password);
    		dest.writeInt(_age);
    	}
    
    	public static final Parcelable.Creator<ParcelData> CREATOR=new Creator<ParcelData>() {
    
    		@Override
    		public ParcelData createFromParcel(Parcel source) {
    			ParcelData registerData=new ParcelData();
    			registerData._account=source.readString();
    			registerData._password=source.readString();
    			registerData._age=source.readInt();
    			return registerData;
    		}
    
    		@Override
    		public ParcelData[] newArray(int size) {
    			
    			return new ParcelData[size];
    		}
    		
    	};
    }
    
    注:

    1、需实现Parcelable。

    2、每一个变量都必须要有对应的Set和Get方法。

    3、需重载writeToParcel写入数据。

    4、必须实现Parcelable.Creator<ParcelData> CREATOR,而且必须为public静态。在实现时还要重载createFromParcel来读取数据。

    5、TransData需要被TransDataA和TransDataB共同引用,为了确保正确,可以将TransData设置为Library,然后在TransDataA和TransDataB中引用。可参看下图



    转载请注明出处 Android跨应用间的数据传输


  • 相关阅读:
    ICONS-图标库
    图形资源
    vue项目中,如果修改了组件名称,vscode编辑器会在引入修改组件的名字处提示红色波浪线 The file is in the program because:Imported via xxx Root file specified for compilation .
    接口在dev环境报跨域问题(has been blocked by CORS policy:Response to preflight request doesn't pass access control check:No 'Access-Control-Allow-Origin' header ispresent on the requested resource.),qa环境正常
    阿里云occ的图片文件URL用浏览器直接打开无法访问,提示This XML file does noe appear to have any style information associated with it. The document tree is shown below.
    vue 项目使用element ui 中tree组件 check-strictly 用法(父子不互相关联的反显情况)
    高德地图进行线路规划绘制标记点操作(vue)
    vue中实现拖拽调整顺序功能
    2021-01-22 浏览器相关知识
    2021-01-22 js 相关知识点
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7605035.html
Copyright © 2011-2022 走看看