【寫框架】基於編譯時註解打造ActivityBus,一鍵傳值

weixin_34320159發表於2017-07-27

首先感謝大家閱讀這篇文章
日常開發中,經常會遇到Activity和Activity,Activity和Fragment之間的傳值場景,通常,大家會這麼處理:
Activity和Activity之間傳值
首先在起始Activity進行存值操作

Intent intent = new Intent(activity, TargetActivity.class);
        intent.putExtra("age", 35);
        intent.putExtra("name", Jordan);
        intent.putExtra("person", (Serializable) new Person());
        activity.startActivity(intent)
        activity.startActivityForResult(intent, 100)//如果需要返回值

然後在目標Activity取值操作

        int age = getIntent().getIntExtra("age", 0);
        String name = getIntent().getStringExtra("name", "");
        Person person = (Person) getIntent().getSerializableExtra("person");

Activity和Fragment之間傳值
存資料

public static TargetFragment newInstance(int age,String name,Person person) {
        TargetFragment target = new TargetFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("age",age);
        bundle.putString("String",position);
        bundle.putSerializable("person",person);
        target.setArguments(bundle);
        return target;
    }

取資料

int age= getArguments().getInt("age");
String name = getArguments().getString("name ");
Person person= (Person )getArguments().getSerializable("person");

是不是覺得很繁瑣,要寫這麼多模板程式碼,生命苦短,青春短暫。有強迫症的同學甚至會為每個傳值變數取個常量名字,如果有工具能自動生成這些模板程式碼,我們只用在目標Activity或者Fragment直接呼叫資料就好了。
咳咳咳,那麼就請大家來嘗試下實現這個需求的:
ActivityBus


ActivityBus基於編譯時註解開發,自動生成Activity或者Fragment代理類,代理類中封裝了以上的傳值和取值的程式碼,使用者只需在目標Activity或者Fragment中需要傳值的變數上新增註解就可以完成一鍵傳值。節省下來的時間至少可以讓我們在這炎炎夏日抽空喝杯涼開。

那麼我們就直接開搞吧

在Activity間傳值

第一步:新增註解

@RequestParam:在目標Activity的需要傳值的成員變數上新增該註解。
@ActivityBus:如果你需要呼叫startActivityForResult(),在目標Activity 上新增該註解,並設定requestCode。

@ActivityBus(requestCode = 100)
public class TargetActivity extends AppCompatActivity {
    @RequestParam
    public int age;
    @RequestParam
    public String name;
    @RequestParam
    public Person person;
    ...
}
第二步:傳遞資料

編譯以後,ActivityBus會自動生成代理類,如TargetActivityBus,名稱格式為【目標Actiity】+Bus,就是說,把你的Activty變成了一輛公交車,可以帶客了,乘客就是你要傳輸的資料。之後呼叫代理類的goActivity()傳入所需的資料即可。

public class MainActivity extends AppCompatActivity {
    ...
    TargetActivityBus.goActivity(this,1,"Hello",new Person("Entity"));
    ...
}
第三步:在目標Activity中進行註冊

在目標Activity中呼叫register(),相當於告訴公交車,我要到這來。乘客到這站就可以下車了。接下來你就可以對乘客do anything了。

@ActivityBus(requestCode = 100)
public class TargetActivity extends AppCompatActivity {
    @RequestParam
    public int age;
    @RequestParam
    public String name;
    @RequestParam
    public Person person;
...
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        ...
        TargetActivityBus.register(this);
        tv_name.setText("My name is"+name);
    }
...
}

Activty和Fragment間傳值

在Fragment中使用更簡單,只需要兩步。

第一步:新增註解
public class TargetFragment extends Fragment {
    @RequestParam
    public int aInt;
    @RequestParam
    public String aString;
    ...
}
第二步:傳遞資料

呼叫Fragment代理類的newInstance()方法進行傳值。

public class MainActivity extends AppCompatActivity {
    ...
    TargetFragment targetFragment = TargetFragmentBus.newInstance(1,"Hello");
    getSupportFragmentManager().beginTransaction().add(R.id.fl_fragment, targetFragment).commit();
    ...
}

支援傳值的資料型別

支援傳值的資料型別基本包括了日常開發的大部分資料型別,其中 List,Set,Map也是同樣簡單的一鍵傳值。實體型別需要實現Serializable介面。

  • Base type : boolean,byte,char,short,int,long,float,double,String
  • Base array type : boolean[],byte[],char[],short[],int[],long[],float[],double[],String[]
  • Container : List,Set,Map
  • Serializable : 實現Serializable介面的所有實體

結尾

ActivityBus只適用模組內或者依賴模組間的顯示呼叫,並不具備模組化元件間呼叫的能力。不過夠用就行。如果對你有幫助,可以點個star支援下。具體的使用,請點Github傳送

相關文章