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跨应用间的数据传输


原文地址:https://www.cnblogs.com/sparkleDai/p/7605035.html