在有些项目中,会有多个应用出现,这样应用间的数据传输就成了必然。那应用间的数据传输要怎么实现呢?我们知道,在跨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\nSerialNo=" + _serialData.GetSerialNo() + "\nWeight=" + _serialData.GetWeight() + "\n"; } if (_parcelData != null) { info = "ParcelData\nAccount=" + _parcelData.GetAccount() + "\n" + "Password=" + _parcelData.GetPassword() + "\n" + "Age=" + _parcelData.GetAge() + "\n"; } _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中引用。可参看下图