=====
在掘金群裡小夥伴的提醒下, 發現在activity意外銷燬重啟的情況下, 會造成拿不到資料的問, 所以文章內介紹的內容, 暫時隨意當做高風險野路子看看~
一不小心隔了大半年沒有寫部落格了,這大半年從一個小菜雞變成了一個大(pang)菜雞。。。好吧,進入正題吧
-
Q:MainActivity跳到TargetActivity時附帶資料要怎麼做?
-
A:不就是intent附帶資料嗎?或者sp/檔案存一下等等方式....
-
Q:那如果是沒有實現序列化的資料呢?
-
A:序列化一下唄...
-
Q:業務原因/歷史原因....這個Bean類要實現序列化的話牽扯到太多東西了,改動成本太大,例如:Bean類裡面有Data類,Data類裡面又有Other類........這樣的問題
-
A:..???..???...????!!!!!??!
開始埋頭苦想
這埋的雷夠巧妙啊,不過難不倒我,這個靈機一動動~誒,我可以這樣做:
在跳轉的時候,先用一個靜態變數引用資料,等TargetActivity起來的時候,再把靜態變數置為null,哎呀,一不小心還注意到了要避免記憶體洩漏,太棒了!
public class TargetActivity extends AppCompatActivity {
// 臨時承載資料
private static Bean sBean;
// activity起來的時候真正引用到資料
private Bean mBean;
/**
* 啟動TargetActivity必須統一走這個方法
* @param context c
* @param bean bean
*/
public static void start(Context context, Bean bean) {
Intent starter = new Intent(context, TargetActivity.class);
// 靜態變數先拿著
sBean = bean;
context.startActivity(starter);
}
{
// 成員變數拿到引用
mBean = sBean;
// 靜態變數置空,防止記憶體洩漏
sBean = null;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);
Log.i("LiuZh", "onCreate: " + mBean.name + " " + mBean.age);
}
}
複製程式碼
總感覺這種拍腦袋就搞出來的騷操作有點不太對勁啊
對了!如果有兩個地方依次相接呼叫TargetActivity.start(Context,Bean)
方法,第一個start呼叫還沒開始建立activity呢,第二個start就把sBean重新賦值了,那兩個activity就拿到了同一個資料.....不行,這樣就亂了,得規避一下這問題---(至於有沒有允許啟動多個相同activity的需求,反正我有....也總會有的)
這樣的話,我可以把start方法鎖住,然後執行完了sBean = null;
這個語句再解鎖?
那要怎麼寫呢,那就給start方法加個synchronized吧,startActivity語句走完就阻塞住,等activity起來拿到資料的時候就解阻塞,好像可以
接下來就是,要怎麼阻塞呢?而且阻塞的話千萬不能在主執行緒,也就意味著我需要在子執行緒內鎖程式碼塊,在子執行緒內阻塞。這樣的話,就在子執行緒用一個while(flag)吧,activity拿完資料就修改flag通知一下,哦了,啪啪就是敲
public class TargetActivity extends AppCompatActivity {
// 臨時承載資料
private static Bean sBean;
// activity起來的時候真正引用到資料
private Bean mBean;
private static boolean sNextStartTaskFlag = false;
/**
* 啟動TargetActivity必須統一走這個方法
*
* @param context c
* @param bean bean
*/
public static void start(final Context context, final Bean bean) {
new Thread() {
@Override
public void run() {
super.run();
synchronized (TargetActivity.class) {
sNextStartTaskFlag = false;
Intent starter = new Intent(context, TargetActivity.class);
// 靜態變數先拿著
sBean = bean;
context.startActivity(starter);
// 阻塞住
while (!sNextStartTaskFlag) ;// do nothing
}
}
}.start();
}
{
// 成員變數拿到引用
mBean = sBean;
// 靜態變數置空,防止記憶體洩漏
sBean = null;
// 我ok了, 下一個start可以走了
sNextStartTaskFlag = true;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);
Log.i("LiuZh", "onCreate: " + mBean.name + " " + mBean.age);
}
}
複製程式碼
得,這樣應該沒啥問題了,走你
- MainActivity佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.example.activitydemo.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startTargetActivity"
android:text="走 你" />
</LinearLayout>
複製程式碼
- MainActivity
public class MainActivity extends AppCompatActivity {
private Activity mContext;
private Bean mBean = new Bean();
{
mContext = this;
mBean.name = "LiuZh";
mBean.age = 22;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startTargetActivity(View view) {
TargetActivity.start(mContext, mBean);
}
}
複製程式碼
- 走你
哦喲,好像還挺不錯的,好,作為一個有追求的小碼渣,還是來自測一下吧,用多個執行緒來瘋狂呼叫一下的start方法:
public void startTargetActivity(View view) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2; i++) {
Bean bean = new Bean();
bean.name = "thread_1_LiuZh_" + i;
bean.age = i;
TargetActivity.start(mContext, bean);
Log.i("LiuZh", "Thread_1: " + i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2; i++) {
Bean bean = new Bean();
bean.name = "thread_2_LiuZh_" + i;
bean.age = i;
TargetActivity.start(mContext, bean);
Log.i("LiuZh", "Thread_2: " + i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2; i++) {
Bean bean = new Bean();
bean.name = "thread_3_LiuZh_" + i;
bean.age = i;
TargetActivity.start(mContext, bean);
Log.i("LiuZh", "Thread_3: " + i);
}
}
}).start();
}
複製程式碼
- 走你
哦了,從Log看起來沒問題了,看看是不是有6個activity起來了吧,看模擬器去吧
啥?圖?
沒圖!自個跑一遍吧