android#简单实现一个依赖注入,简化开发

    科技2024-05-23  78

    第一步: 自定义注解

    package com.example.myapplication.core.annon; import java.lang.annotation.*; /** * 绑定视图 * @Author lyr * @create 2020/10/7 12:54 */ @Target({ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface BindView { int view(); /* * @View(view = R.layout.main_activity) * class Activity{ * @View(view=R.id.btn) * private Button btn; * * } * * */ } package com.example.myapplication.core.annon; import java.lang.annotation.*; /** * @Author lyr * @create 2020/10/7 13:14 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface ViewModel { /* * 自动初始化并且注入 * * @ViewModel * private MainActivityViewModel vm; * * */ /* * class MainActivityViewModel extends AndroidViewModel { * String username; * String password; * * } * * */ }

    第二步,使用模板方法 实现一个 BaseActivity

    package com.example.myapplication.core; import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; import androidx.databinding.DataBindingUtil; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.ViewModelProviders; import com.example.myapplication.core.annon.BindView; import com.example.myapplication.core.annon.ViewModel; import com.example.myapplication.databinding.ActivityMainBinding; import java.lang.reflect.Field; /** * 通过注解 自动依赖注入 的实现类 * * @Author lyr * @create 2020/10/7 12:56 */ public abstract class BaseAnnotationActivity extends BaseActivity { protected ActivityMainBinding binding; protected int viewId = -1; /** * 设置了 final * 禁止重写 onCreate 方法 * * @param savedInstanceState instanceState */ @Override protected final void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //初始化视图 initCustomView(); //依赖注入 fieldAutoInject(); //自动数据双向绑定 autoDataBind(); //回调 onCreateCustom(); } /** * 绑定视图 */ private void initCustomView() { BindView bindView = this.getClass().getAnnotation(BindView.class); if (bindView != null) { this.viewId = bindView.view(); setContentView(viewId); } } /** * 依赖注入 */ private void fieldAutoInject() { for (Field f : getClass().getDeclaredFields()) { f.setAccessible(true); BindView view = f.getAnnotation(BindView.class); if (view != null) { int id = view.view(); try { f.set(this, findViewById(id)); } catch (IllegalAccessException e) { Log.e("init error", "绑定视图出现了异常"); } } } } /** * 自动数据双向绑定 */ private void autoDataBind() { // vm = ViewModelProviders.of(this).get(MainActivityViewModel.class); // binding = DataBindingUtil.setContentView(this, R.layout.activity_main); // //设置数据源 // binding.setVm(vm); // binding.setLifecycleOwner(this); for (Field f : getClass().getDeclaredFields()) { f.setAccessible(true); ViewModel viewModel = f.getAnnotation(ViewModel.class); Class type = f.getType(); if (viewModel != null && AndroidViewModel.class.isAssignableFrom(type)) { try { f.set(this, ViewModelProviders.of(this).get(type)); AndroidViewModel vm = (AndroidViewModel) f.get(this); binding = DataBindingUtil.setContentView(this, viewId); //设置数据源 setViewModel(binding); binding.setLifecycleOwner(this); } catch (Exception e) { Log.e("bindView", "绑定数据异常"); } break; } } } /** * 自定义回调 */ protected abstract void onCreateCustom(); /** * binding.setVm(vm); * @param binding */ protected abstract void setViewModel(ActivityMainBinding binding); }

    示例代码

    package com.example.myapplication; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.example.myapplication.core.BaseAnnotationActivity; import com.example.myapplication.core.annon.BindView; import com.example.myapplication.databinding.ActivityMainBinding; @BindView(view = R.layout.activity_main) public class MainActivity extends BaseAnnotationActivity implements View.OnClickListener { // @ViewModel // private MainActivityViewModel vm; @BindView(view = R.id.btn_clear) Button btnClear; @BindView(view = R.id.username) TextView username; @BindView(view = R.id.password) TextView password; @Override protected void onCreateCustom() { // super.onCreate(savedInstanceState); Log.i("info", "on create ..."); // Log.i("info", vm.toString()); Log.i("info", btnClear.toString()); Log.i("info", username.toString()); btnClear.setOnClickListener(this); } /** * binding.setVm(vm); * * @param binding */ @Override protected void setViewModel(ActivityMainBinding binding) { // binding.setVm(vm); } /** * Called when a view has been clicked. * * @param v The view that was clicked. */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_clear: { Log.i("click,trigger","设置焦点"); username.setText(""); password.setText(""); username.requestFocus(); } } } }

    注意项

    如果使用 DataBinding 的话,绑定事件的方法就不好用了,目前还没有办法解决这个问题

    Processed: 0.014, SQL: 9