iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0
Mobile Development

Android 開發經驗三十天系列 第 13

[Android 開發經驗三十天]D13一Dagger(下)

  • 分享至 

  • xImage
  •  

林明進老師:「可以成為一顆大樹,就不要只作一片葉子。」 我想,鍊成鐵人應該是比變成大樹更酷的事。 ^^


tags: 鐵人賽 Templates

今天講Dagger如何在Activity應用
這篇是JAVA喔喔喔!

Q1:@Component?
A:因為前面有創全局應用共用的ApplicationComponent,所以在Activity創一個簡單的Component,並且是依賴在ApplicationComponent,等於也能拿到ApplicationComponent提供的功能OUO
然後跟自己的Module依賴,然後寫個inject讓後面在Activity容易注入

@MainActScoped
@Component(
        dependencies = ApplicationComponent.class,
        modules = {
                MainModule.class
        }
)
public interface MainComponent {
    void inject(MainActivity mainActivity);
}

Q2:@MainActScoped?
A:這個是自定義Scoped,主要是讓他不同Scope的東西分開,可以想成在A Scope跟B Scope是不互通的,A拿A,B拿B提供,然後基本上所有Scope都是依賴Singleton的

@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface MainActScoped {
}

Q3:@Module?
A:一樣提供activity跟context,然後因為我這是mvp,所以在這裡也會提供presenter,然後因為provide提供的有scope,所以module也是那個scope,所以component也必須是那個scope囉

@Module
public class MainModule {

    private AppCompatActivity appCompatActivity;
    public MainModule(AppCompatActivity appCompatActivity){
        this.appCompatActivity=appCompatActivity;
    }

    @Provides
    @MainActScoped
    AppCompatActivity provideActivity(){
        return appCompatActivity;
    }

    @Provides
    @MainActScoped
    Context provideContext(){
        return appCompatActivity;
    }

    @Provides
    @MainActScoped
    MainContract.Presenter<MainContract.View> providePresenter(MainPresenter<MainContract.View> presenter) {
        return presenter;
    }
}

Q4.:@Provides?
A:provides就是要提供,提供你要提供給他也要標示inject,標示他是可以提供,可以注入的

如提供presenter,要在presenter下inject
@Inject 一般情況下是標注成員屬性和構造函數
標注的成員屬性不能是private,Dagger 2 還支持方法注入
@Inject還可以標注方法

Q:不能使用Inject?
A:不能使用的狀況有
* 介面沒有構造函數
*第三方repository/library的類不能被標注
*構造函數中的參數必須配置


public class MainPresenter <V extends  MainContract.View> extends BasePresenter<V> implements MainContract.Presenter<V> {

    /*@Inject 一般情況下是標注成員屬性和構造函數
    標注的成員屬性不能是private,Dagger 2 還支持方法注入
    @Inject還可以標注方法
*/

    /**contract presenter -> implement  (di  goto true)
     *  contract view -> getView( )->getfun implement->activity
     *  attacher bind view*/
    /*不能使用的狀況有
     * 介面沒有構造函數
     *第三方repository/library的類不能被標注
     *構造函數中的參數必須配置
     */
  @Inject
   public  MainPresenter(APIService apiService, CompositeDisposable compositeDisposable){
       super(apiService,compositeDisposable);
   }



    @Override
    public void getUserList() {
       getView().showProgressDialog("loading");
       /*CompositeDisposable 多個訂閱時使用 方便管理*/
        getCompositeDisposable().add(getApiService()
        .getUsers()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeWith(new DisposableObserver<List<Users>>() {
            @Override
            public void onNext(List<Users> value) {
                getView().setData(value);
            }

            @Override
            public void onError(Throwable e) {
                Log.e("kk", "onError: "+e);
            }

            @Override
            public void onComplete() {
                getView().dismissProgressDialog();
            }
        }));


    }


}

最後就是Activity啦!
第一個先將Compomnent綁入,下面applicationComponent也要寫因為你depency有用他(可以看mainComponent),
第二個要綁mainModule(要new他),第三步就是build起來了!!

@Component(
        dependencies = ApplicationComponent.class,
        modules = {
                MainModule.class
        }
)

mainComponent = DaggerMainComponent.builder()
.applicationComponent(((Application) getApplication()).getApplicationComponent())
.mainModule(new MainModule(this))
.build();
像之前有提供getApiService跟presenter,所以寫@Inject就可以注入使用了

public class MainActivity extends BaseActivity implements MainContract.View{

    @Inject
    APIService getApiService;

    @Inject
    MainContract.Presenter<MainContract.View> presenter;

    public CompositeDisposable compositeDisposable;
    private MainComponent mainComponent;
    private TextView tv;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mainComponent = DaggerMainComponent.builder()
                .applicationComponent(((Application) getApplication()).getApplicationComponent())
                .mainModule(new MainModule(this))
                .build();

        mainComponent.inject(this);
        tv=findViewById(R.id.tv);
        button=findViewById(R.id.button);
        presenter.onAttached(this);
        //getUserList();
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.getUserList();
            }
        });

    }

    public void getUserList(){
        getApiService.getUsers().subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<Users>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<Users> value) {
                        Log.e("tv", "onNext: "+value.get(0).getEmail() );
                        tv.setText(value.get(0).getUsername());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("yy", "onError: "+e );
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    @Override
    public void setData(List<Users> usersList) {
        Log.e("yy", "setData: "+usersList.get(0).getEmail());
        tv.setText(usersList.get(0).getUsername());

    }
}

大概就是這樣啦!


上一篇
[Android 開發經驗三十天]D12一Dagger(上)
下一篇
[Android 開發經驗三十天]D14一Spring Boot IOC
系列文
Android 開發經驗三十天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言