Android:Activity與Fragment、Service之間的數據通訊

一、Activity向Fragment傳遞數據?

  • 在Activity中建立Bundle,將數據以putString(key,value)形式放入bundle中,最後經過setArguments(bundle)方法,將其關聯,在Fragment【與Activity依附的Fragment】中直接經過getArguments().getString()來獲取。android

  • 直接經過強轉將其強轉爲Activity,即調用Fragment所依附的Activity中的方法。面試

二、Fragment將數據傳遞給Activity?

基本方法:接口回調;性能優化

  • 在fragment定義一個內部回調接口,再讓包含這個FragmentActivity實現這個回調接口,fragment就能夠調用這個接口中的方法,將數據傳遞給Activity。bash

  • Activity實現完接口後,又怎樣把數據傳遞給Fragment,利用Fragment剛添加到Activity時的時候調用的生命週期方法的onAttch()方法,咱們就在該方法中檢查相應的Activity是否實現了Fragment當中定義的內部接口。就是對它進行了類型轉換,而後賦值給咱們Fragment中定義的接口。架構

  • 當一個Fragment從Activity當中剝離時,就會走到生命週期的onDetach()方法,在此要將傳遞進來的Activity對象釋放掉,不然會影響Acitvity銷燬,產生內存泄漏。框架

public class fragment1 extends Fragment implements View.OnClickListener{
    //2.一、用來與外部Activity交互,獲取宿主Activity
    private FragmentListener listener;
    //一、首先定義全部Activity必須實現的接口方法。
    public interface FragmentListener{
        void process(String str);
    }
    //fragment被加載到Activity時回調
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //判斷activity是否實現了FragmentListener方法
        if (activity instanceof FragmentListener){
            listener = (FragmentListener) activity;//獲取到宿主Activity,並給你賦值。
        }else{
            throw new IllegalArgumentException("activity must implements Fragment");
            //不然的話,會拋出activity must implements Fragment[Activity必須關聯Fragment]異常。
        }
    }
    @Override
    public void onClick(View v) {
        listener.process(str:"我是接口");//3.一、執行回調
    }
    //把傳遞進來的activity對象釋放掉
 
    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;//進行銷燬,避免形成內存泄漏。
    }
}
複製代碼
public class FragmentActivity1 extends Activity implements fragment1.FragmentListener {
 
        @Override
        public void process(String str) {
            // TODO: 2019/3/19
        }
}
複製代碼

除此之外咱們想要完成Activity與Fragment之間的數據傳遞還可使用:第三方框架Eventbus、廣播。ide

三、Activity與Service數據通訊?

三種方式:函數

一、綁定服務,利用ServiceConnection類,同時讓Activity實現該類,重寫該類中的兩個方法,即綁定成功()和綁定失敗()。性能

  • 讓咱們的ServiceActivity去實現ServiceConnection接口,實現接口以後,重寫onServiceConnected()和onServiceDisconnected()兩個方法。
  • 首先咱們要建立好一個Binder對象,接下來在OnServiceConnected當中獲取到該Binder對象。最後利用Binder當中setData()方法來向Service傳遞數據。

二、簡單通訊,利用Intent進行傳值(Intent組件在activity之間、activity與fragment之間數據通訊都會用到),該方法簡單,可是也只能傳遞較簡單的數據。優化

//在ServiceActivity中進行啓動和中止服務操做
     
   @Override
        public void onClick(View v){
            switch (v.getId()){
                case R.id.btStartService://啓動服務
                    intent.putExtra(name:"data",value:"data");//(key,value)
                    startService(intent);
                    break;
                case R.id.btStopService://啓動服務
                    stopService(intent);
                    break;
            }
        }
複製代碼
//Service中
public int onStartCommand(final Intent intent,int flags,int startId){
    data = intent.getStringExtra(name:"data");//接收從Activity中傳遞來的值。
    return super.onStartCommand(intent,flags,startId);
} 
複製代碼

三、利用callback接口,將Handler來監聽服務中的進程的變化(會有子線程到主線程的切換,所以用到了Handler)。

  • Service內部是如何實現的呢?
  • 首先添加一個公開的Callback接口,經過Activity來實現該接口。
public interface Callback{
    void onDataChange(String data);
}
複製代碼
  • 新建一個Binder類,在Binder內部定義getMyService()方法用來返回當前MyService的一個對象,讓Activity能夠添加該事件的綁定。
public class Binder extends android.os.Binder{
    public void setData(String data){
        MyService.this.data = data;
    }
    public MyService getMyService(){
        return MyService.this;
    }
}
複製代碼
  • 那麼外部Activity是如何添加綁定的呢?
  • 首先onServiceConnected()方法,一旦調用該方法,就說明咱們的Service與Activity之間綁定成功了。實現過程:調用setCallback()方法,實現onDataChange()方法。除此以外,因爲咱們onDataChange()是在子線程中執行【在子線程中更新UI,要使用到Handler】,在此咱們使用Handler發送一個Message,在主線程中咱們定義了一個Handler,並實現了它的handlerMessage()方法,即將任務從子線程切換到了主線程,讓主線程來進行UI操做。
private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg){
            super.handleMessage(msg);
        }
    };
     //一旦綁定成功就會執行該函數
    @Override
    public void onServiceConnected(ComponentName componentName,Ibinder iBinder){
        myBinder = (MyService.Binder) iBinder;
        myBinder.getMyService().setCallback(new MyService.callback() {
            Message msg = new Message();
            Bundle b = new Bundle();
            b.putString("data",data);
            msg.setData(b);
            handler.sendMessage(msg);
        });
    }
複製代碼

最後送福利了,如今關注我而且加入羣聊能夠獲取包含源碼解析,自定義View,動畫實現,架構分享等。 內容難度適中,篇幅精煉,天天只需花上十幾分鍾閱讀便可。 你們能夠跟我一塊兒探討,歡迎加羣探討,有flutter—性能優化—移動架構—資深UI工程師 —NDK相關專業人員和視頻教學資料,還有更多面試題等你來拿~ 羣號:661841852

QQ截圖20190510143109.jpg
點擊連接加入羣聊【Android開發行業交流】: jq.qq.com/?_wv=1027&a…
相關文章
相關標籤/搜索