1. 程式人生 > >Android元件化之不同模組間 互動(activity互相跳轉,資料互相傳遞,互相呼叫函式)

Android元件化之不同模組間 互動(activity互相跳轉,資料互相傳遞,互相呼叫函式)

 轉載請標明地址:https://blog.csdn.net/gaolei1201/article/details/77601027

在元件化之前,業務發展不是很快的時候,這樣是比較合適的,能一定程度地保證開發效率。

慢慢地程式碼量多了起來,開發人員也多了起來,業務發展也快了起來,或者由多個專案其實可以共用一些模組時,這時單一工程開發模式就會顯露出一些弊端:

  • 耦合比較嚴重(因為沒有明確的約束,「元件」間引用的現象會比較多)
  • 業務模組重用性較差
  • 業務方的開發效率不夠高(只關心自己的元件,卻要編譯整個專案,與其他不相干的程式碼糅合在一起)

為了解決這些問題,就採取了「元件化」策略它能帶來這些好處:

  • 加快編譯速度(不用編譯主客那一大坨程式碼了)
  • 業務模組可以在不同專案中應用
  • 方便QA有針對性地測試
  • 提高業務開發效率

下面的這張圖是專案依賴關係

由於元件化的內容網上資料較多,我來講一些不一樣的。模組化是用來降低耦合度,但是有時候難免會和其他模組有些互動(這也是自己在公司開發專案中遇到的) ,一個模組可以呼叫被依賴模組的類方法,而被依賴模型不能引入依賴模組類。簡而言之就是,依賴只能單向,不能是雙向,就算你想Android Studio也不讓。但有時候被依賴的模組也需要一些依賴模組的資料怎麼辦?我就講一下不同模組之間怎麼互動的。

一、Activity之間跳轉,有幾種方式:

1.隱式Intent,要跳轉的活動在Manifest.xml中宣告,然後呼叫startActivity(new Intent(“com.example.boost”))

<activity android:name="com.example.boost.BoostActivity">
   <intent-filter>
        <action android:name="com.gaolei" />
    </intent-filter>
</activity>


2. manifest.xml中活動的資料設計URI來接受跳轉,然後呼叫startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(“activity:// applock”)))。更多內容可瞭解路由器:

https ://blog.csdn.net/zhaoyanjun6/article/details/76165252

<activity
    android:name=".module.ui.activity.RecommendGuideActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="activity" />
        <data android:host="applock" />
    </intent-filter>
</activity>

3.利用反射

Class clazz=Class.fromName("com.clean.spaceplus.MainActivity")
startActivity(this,clazz);

如圖4所示,可以看演示中的程式碼,就是把不同模組的一些類註冊到一個都依賴的模組(如專案中的介面的ModuleDelegate),然後一個模組就可以電子雜誌到其他模組的一些類物件,從而呼叫那個類的方法進行一些操作,如跳轉一些活動。

下面是ModuleDelegate來註冊不同模組的一些類,供其他模組呼叫

public class CleanDelegate {

    private final Map<String, IDelegateFactory> factoryMap = new HashMap<>();

    private static final CleanDelegate mInstance = new CleanDelegate();

    private CleanDelegate() {
    }

    public static CleanDelegate getInstance() {
        return mInstance;
    }

    public static void register(String key, IDelegateFactory factory) {
        mInstance.factoryMap.put(key, factory);
    }

    public Bundle getData(String factoryCode, int code, Bundle args, Object... extras) throws DelegateException {
        IDelegateFactory factory = factoryMap.get(factoryCode);
        if (factory != null) {
            IDataDelegate transfer = factory.getDataTransfer(code);

            if (transfer != null) {
                return transfer.getData(args, extras);
            }
        }

        throw new DelegateException("unknow data transfer");
    }
}

4. 推薦使用第三方框架ActivityRouter,詳情可搜尋相關文章

二、模組間如何通訊,也有幾種方法

1. 推薦使用第三方框架EventBus,詳情可搜尋相關文章

2. 就是把不同模組的一些類註冊到一個都依賴的模組(如專案中的介面的ModuleDelegate),然後一個模組就可以電子雜誌到其他模組的一些類物件,從而呼叫那個類的方法進行一些操作,如獲取一些資料。

下面這個類是防毒軟體模組呼叫升壓模組的一些資料

public class AntivirusActivity extends Activity {

    TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_submodule2);
        text = findViewById(R.id.text);
    }

    public void getDataFromOtherModule(View view) {
        Bundle bundle;
        try {
            bundle = new Bundle();
            bundle.putString("gaolei", "beauty");
            Bundle bundle1 = ModuleDelegate.getInstance().getData(BoostDelegateConsts.FACTORY, BoostDelegateConsts.DataCode.getTotalMemoryByte, bundle, AntivirusActivity.this);
            String result = bundle1.getString("result");
            text.setText(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


4. 如果呼叫其他模組的一些方法是執行一些耗時操作,那麼我們就可以在其他模組的子執行緒中傳送廣播,這個模組來接受。廣播不管是不是在子執行緒中都可以傳送出去,關於廣播是最基本的我就不多說

/**
 * @author gaolei
 * @Description:供Antivirus模組呼叫的類
 *
 */
public class GetSyncData implements IDataDelegate {
    @Override
    public Bundle getData(Bundle args, Object... extras) throws DelegateException {
        if (extras.length > 0 && extras[0] != null) {
            if (extras[0] instanceof Context) {
                final Context context = (Context) extras[0];
                new Thread() {
                    public void run() {

                        try {
                            new Thread() {
                                public void run() {
                                    try {
                                        //模擬耗時操作,在這個執行緒裡可以做耗時操作,然後把資料通過廣播傳出去
                                        Thread.sleep(3000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    Bundle bundle = new Bundle();
                                    bundle.putString("result", "這是一條非同步獲取的資料從Boost模組");
                                    Intent intent = new Intent("com.example.getdata");
                                    intent.putExtras(bundle);
                                    context.sendBroadcast(intent);
                                }
                            }.start();


                        } catch (Throwable e) {

                        }
                    }
                }.start();
            }
        }
        return null;
    }
}
public class AntivirusActivity extends Activity {

    TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_antivirus);
        text=findViewById(R.id.text);

        IntentFilter filter=new IntentFilter("com.example.getdata");
        DataReceiver dataReceiver=new DataReceiver();
        registerReceiver(dataReceiver,filter);
    }

    public void getDataFromOtherModule(View view) {

        Bundle bundle;
        try {
            bundle = new Bundle();
            bundle.putString("gaolei", "beauty");
           Bundle bundle1= ModuleDelegate.getInstance().getData(BoostDelegateConsts.FACTORY, BoostDelegateConsts.DataCode.getTotalMemoryByte,bundle,AntivirusActivity.this);
            String result=bundle1.getString("result");
            text.setText(result);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }  
    public void getSyncDataFromOtherModule(View view) {

        Bundle bundle;
        try {
            bundle = new Bundle();
            //這個地方是呼叫Boost模組,獲取非同步資料
           Bundle bundle1= ModuleDelegate.getInstance().getData(BoostDelegateConsts.FACTORY, BoostDelegateConsts.DataCode.getSyncData,bundle,AntivirusActivity.this);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public class DataReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle=intent.getExtras();
            String data=bundle.getString("result");
            text.setText(data);
        }
    }
}