以下内容为复习总结,若有幸被大神看到,望指正其不准,补充其不足。万分感谢!!!
Activity作为应用与用户直接交互的组件,要直观的向用户显示一些数据和信息,因此Activity之间彼此传值就边的很重要了。那么Activity之间传值有哪些方式呢?
Intent在android中有着重要的左右,它不仅是连接三大组件的桥梁,同时也肩负起数据传输的重任。
Intent可以传递的数据类型非常的丰富,包括java的基本数据类型和String类型以及他们的数组集合形式;除此之外还可以传递Bundle,和实现了Serializable和Parcelabe接口的对象。
传递Activity_send,设置数据
Intent intent = new Intent(this,ActivityReceive.class);
//窗体传值
intent.putExtra("name","张三");
intent.putExtra("age",20);
intent.putExtra("isMerry",false);
//设置数组
intent.putExtra("stuHobby",new String[]{"篮球","羽毛球","足球"});
//设置集合数值
ArrayList list = new ArrayList();
list.add("北京");
list.add("广东");
list.add("美国");
//设置数值到Intent 中
intent.putStringArrayListExtra("stuCitys",list);
//开启Activity
startActivity(intent);
接收ActivityReceive,取出数据
//从Intent 中取出传递过来的数据
Intent intent = getIntent();
//取出普通数据
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);
boolean isMerry = intent.getBooleanExtra("isMerry",false);
//取出数组数据
String[] hobbys = intent.getStringArrayExtra("stuHobby");
String hobby = Arrays.toString(hobbys);
//取出ArrayList 集合数据
ArrayList<String> citys =intent.getStringArrayListExtra("stuCitys");
String city = Arrays.toString(citys.toArray());
传递Activity_send,设置Bundle
//创建意图对象
Intent intent = new Intent(MainActivity.this,ActivityReceive.class);
//用数据捆传递数据
Bundle bundle = new Bundle();
bundle.putString("data", str);
//把数据捆设置改意图
intent.putExtra("bun", bundle);
//激活意图
startActivity(intent);
接收ActivityReceive,取出Bundle
//获取Bundle
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("bun");
String str = bundle.getString("data");
Android中序列化有两种实现方式:分别是实现了Serializable和Parcelabe接口的对象。这两者实现方式不同。
创建序列化对象
import java.io.Serializable;
class DataBean implements Serializable {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
传递Activity_send,设置序列化对象
//创建意图
Intent intent = new Intent(MainActivity.this,ActivityReceive.class);
DataBean bean = new DataBean();
//通过set方法把数据保存到DataBean对象中
bean.setName("啦啦");
bean.setSex("男");
intent.putExtra("key", bean);
startActivity(intent);
接收ActivityReceive,取出取出序列化对象
Intent intent = getIntent();
//反序列化数据对象
Serializable se = intent.getSerializableExtra("key");
if(se instanceof DataBean){
//获取到携带数据的DataBean对象db
DataBean db = (DataBean) se;
//TODO
}
根据静态变量的特点,调用时无需创建对象直接使用类名就可以引用。
可以在目标Activity中定义需要接收的静态参数变量,也可以定义一个静态变量工具类,统一定义。在跳转之前对其赋值。
定义静态变量工具类
public class Constant {
public static String mEmail;
public static String mPassword;
}
传递Activity_send,设置传递数据
Intent intent = new Intent(OneActivity.this,TwoActivity.class);
Constant.mEmail = mEmail;
Constant.mPassword =mPassword;
startActivity(intent);
接收ActivityReceive,取出静态变量
String mEmail = Constant.mEmail;
String mPassword = Constant.mPassword;
//TODO
以下是通过外部存储方式传递
一般外部存储传递优先考虑此方式
这里传递数据保存到sp中,在开启另一个Activity前,从sp中读取,并操作
定义sp工具类
public class SPUtils {
public SPUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
*/
public static void put(Context context, String key, Object object) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String) {
editor.putString(key, (String)object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
if (object != null) {
editor.putString(key, object.toString());
}
}
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
String spString = sp.getString(key, (String) defaultObject);
return spString ;
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
}
传递Activity_send,设置传递数据
SPUtils.put(getView().getContext(),"test","师太你就从了老衲吧");
Intent intent = new Intent(Activity_send.this,TwoActivity.class);
startActivity(intent);
接收ActivityReceive,取出sp中数据
String test= (String) SPUtils.get(ActivityReceive.this, "test", "");
//TODO
与sp传递方式类似,都是将数据存储到本地,启动目标Activity时,去本地取出数据,具体操作此处不做介绍
EventBus是由greenrobot组织贡献的一个Android事件发布/订阅轻量级框架。EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。
官网地址:http://greenrobot.org/eventbus/
翻译:http://blog.csdn.net/poorkick/article/details/55099311
用github开源文档上的介绍就是:一个Android平台的事件总线框架,它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。
开发中我们都知道,很多时候要在Activty与Activty间,Activty与Fragment等之间传递数据进行交互,操作起来很不方便,我们以前可能会用到接口回调,或是用观察者模式来实现,或是发广播等等。这们操作不仅仅代码量大,而且代码耦合性高,性能不佳,也不便于维护。例如:两个Fragment之间的通信你会怎么实现? 按照Android官方给的建议的解决方法如下: Communicating with the Activity,思路就是Activity实现某个接口,然后在Fragment-A关联上Activity之后将Activity强转为接口类型,然后在某个时刻Fragment中回调这个接口,然后再从Activity中调用Fragment-B中方法。这个过程是不是有点复杂呢? 如果你也这么觉得,那也就是你继续看下去的理由了。
给Activity设置主题
它是一种页面内跳转协议,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面,主要用于支持以下几种场景
mango://appwork/man?id=8897&name=angel
public void valldCheck(Uri uri){
PackageManager packageManager = getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
List activities = packageManager.queryIntentActivities(intent, 0);
boolean isValid = !activities.isEmpty();
if (isValid) {
startActivity(intent);
}
}
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:scheme="mango"
android:host="appwork"
android:path="/man"
/>
intent-filter>
activity>
先获取服务器给我们的uri,然后跳转到本应用的activity或者其它应用的activity,可以使用如下方式;这个协议需要双方约定好,其实大公司用的比较多,因为像阿里腾讯同时有好几个app装在用户的手机上,需要相互调用
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("mango://appwork/man?id=8897&name=angel"));
startActivity(intent);
而在H5页面的时候可以通过WebViewClient的shouldOverrideUrlLoading方法去解析scheme协议,然后进行相应的跳转
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e(TAG,"shouldOverrideUrlLoading url="+url);
// 根据协议的参数,判断是否是所需要的url
// 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
//假定传入进来的 url = "mango://appwork/man?id=8897&name=angel"(同时也是约定好的需要拦截的)
Uri uri = Uri.parse(url);
// 如果url的协议 = 预先约定的 mango 协议
// 就解析往下解析参数
if ( uri.getScheme().equals("mango")) {
// 如果 authority = 预先约定协议里的 appwork,即代表都符合约定的协议
// 所以拦截url,下面JS开始跳转到native指定页面
if (uri.getAuthority().equals("appwork")) {
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
}
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
}
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME);