Skip to content
Android注解框架,辅助快速开发
Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app add base lib Nov 28, 2019
base add base lib Nov 28, 2019
example_lib
gradle/wrapper
view-inject-annotation update to 0.1.0 Dec 14, 2019
view-inject-api update to 0.1.0 Dec 14, 2019
view-inject-compiler
.gitignore update Nov 10, 2019
README.MD update readme Dec 14, 2019
build.gradle update readme Nov 4, 2019
build_result.txt
config.gradle update to 0.1.0 Dec 14, 2019
gradle.properties 添加javapoet Oct 29, 2019
gradlew init Oct 16, 2019
gradlew.bat init Oct 16, 2019
settings.gradle add base lib Nov 28, 2019

README.MD

编译时注解框架

引用

implementation 'com.huangyuanlove:view-inject-api:0.1.0'
implementation 'com.huangyuanlove:view-inject-annotation:0.1.0'
annotationProcessor 'com.huangyuanlove:view-inject-compile:0.1.0'

@BindView

使用方法: 在application module中

@BindView(id = R.id.xxx)
protected Button buttonOne;

在 library module中

@BindView(idStr = "xxx")
protected Button buttonTwo;

需要注意的是:字段的访问修饰符权限必须大于 protected,在字段使用前调用(一般是在OnCreate、onCreateView)ViewInjector.bind(this);

Activity示例: TestViewInjectActivity.java

Fragment示例: TestViewInjectFragment.java

Adapter示例: ListViewAdapter

@ClickResponder

在application module中

@ClickResponder(id = {R.id.xxx,R.id.yyy})
public void onClickButtonOne(View v) {
  Toast.makeText(TestViewInjectActivity.this, "test_view_inject_one", Toast.LENGTH_SHORT).show();
}

在 library module中

@ClickResponder(idStr = {"xxx","yyy"})
public void onClickButtonTwo(View v) {
  Toast.makeText(TestViewInjectActivity.this, "test_view_inject_two", Toast.LENGTH_SHORT).show();
}

需要注意的是:方法的访问修饰符权限必须大于 protected,在方法使用前调用(一般是在OnCreate、onCreateView)ViewInjector.bind(this); 支持同一个方法绑定到多个view


@LongClickResponder

在 application module中

@LongClickResponder(idStr = {"test_view_inject_two"})
public void onLongClickButtonTwo(View v){
  Toast.makeText(TestViewInjectActivity.this, "long click button two", Toast.LENGTH_SHORT).show();
}

在 library module 中

@LongClickResponder(id = R.id.test_long_click)
public void onLongClick(View v){
  Toast.makeText(TestViewInjectActivity.this, "test_long_click", Toast.LENGTH_SHORT).show();
}

需要注意的是:方法的访问修饰符权限必须大于 protected,在方法使用前调用(一般是在OnCreate、onCreateView)ViewInjector.bind(this); 支持同一个方法绑定到多个view

@IntentValue

用来代替 getIntent().getXXX 或者Fragment中的getArguments().getXXX 使用方式:

@IntentValue(key = "String")
String value = "default"

@IntentValue(key = "parcelableObject",type = IntentValue.PARCELABLE_OBJECT)
ParcelableObject parcelableObject;

@IntentValue(key = "parcelableObjects" ,type = IntentValue.PARCELABLE_ARRAY_OBJECT)
ParcelableObject[] parcelableObjects;

@IntentValue(key = "parcelableObjectArrayList",type = IntentValue.PARCELABLE_ARRAYLIST_OBJECT)
ArrayList<ParcelableObject>  parcelableObjectArrayList;

@IntentValue(key = "serializableObject",type = IntentValue.SERIALIZABLE_OBJECT)
UnParcelableObject serializableObject;

注意: 如果传递的是Parcelable对象,type声明为IntentValue.PARCELABLE_OBJECT

如果传递的是Parcelable对象数组,type声明为IntentValue.PARCELABLE_ARRAY_OBJECT

如果传递的是Parcelable对象ArrayList,type声明为IntentValue.PARCELABLE_ARRAYLIST_OBJECT

如果传递的是序列化对象(实现了Serializable接口),type声明为IntentValue.SERIALIZABLE_OBJECT

在字段使用前(一般是在Activity的onCreate或者Fragment的onCreateView方法中)调用ViewInjector.parseBundle(this);

@UriValue

只支持如下几种类型,并且只能在Activity中使用

@UriValue(key = "name")
String name;
@UriValue(key = "id")
int id;
@UriValue(key = "double")
double aDouble;

@UriValue(key = "float")
float aFloat;

@UriValue(key = "long")
long aLong;

@UriValue(key = "boolean")
boolean aBoolean;

在字段使用前(一般是在Activity的onCreate方法中)调用ViewInjector.parseBundle(this);

@BroadcastResponder

广播分为本地广播和全局广播,注解接收广播接收器之后,需要自己去解注册 使用方式

//在 OnCreate 中注册广播接收器
HashMap<Integer, BroadcastReceiver> broadcastReceiverHashMap = ViewInjector.registerReceiver(this);

//使用注解定义接收广播的action 以及对应的回调方法

@BroadcastResponder(action = {"com.huangyuanblog","com.huangyuanblog.www"})
public void onReceiveBroadcast(Context context, Intent intent){
    Toast.makeText(context,intent.getAction(),Toast.LENGTH_SHORT).show();
}

//type默认本地广播,接收全局广播需要指定type = BroadcastResponder.GLOBAL_BROADCAST
@BroadcastResponder(action = {"com.huangyuanlove",Intent.ACTION_AIRPLANE_MODE_CHANGED},type = BroadcastResponder.GLOBAL_BROADCAST)
public void onReceiveBroadcastOther(Context context, Intent intent){
    Toast.makeText(context,intent.getAction(),Toast.LENGTH_SHORT).show();
}

//在 onDestroy 中解注册

@Override
protected void onDestroy() {
    super.onDestroy();
    if(broadcastReceiverHashMap!=null){
        if(broadcastReceiverHashMap.get(BroadcastResponder.GLOBAL_BROADCAST) !=null){

            unregisterReceiver(broadcastReceiverHashMap.get(BroadcastResponder.GLOBAL_BROADCAST));
        }

        if(broadcastReceiverHashMap.get(BroadcastResponder.LOCAL_BROADCAST) !=null){
            LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiverHashMap.get(BroadcastResponder.LOCAL_BROADCAST));
        }

    }
}

需要注意的是,默认的广播接收器是本地广播,如果需要接收全局广播,比如打开飞行模式等,需要指定type = BroadcastResponder.GLOBAL_BROADCAST 千万别忘记解注册

@RouterModule and @RouterPath

相同的 schema 和 host 中不要有相同的path及path对应的方法名 相同的 schema 和 host 中不要有相同的path及path对应的方法名 相同的 schema 和 host 中不要有相同的path及path对应的方法名

在不同的Provider中提供相同的schema和host会导致Router被覆盖,无法保证路由目标的正确性。

一般以App的名字做schema,模块(module)的名字做host,目标Activity的类名做方法名及path。 比如App的名字为jandan,模块(module)名为 account,目标Activity的类名为LoginActivity 则对应Provider推荐这样写

@RouterModule(schema = "Jandan",host = "account")
public class AccountModuleRouterProvider {
    
    @RouterPath(value = "login")
    public void toLoginActivity(Context context, String userName){
        Intent intent = new Intent(context,LoginActivity.class);
        intent.put("userName",userName);
        context.startActivity(intent);
    }
    
}

//在其他类中使用
Router.to("Jandan://account/login").addParam(this,"userName").done(new Router.InvokeResultListener() {
            @Override
            public void onError(Exception e) {
                Toast.makeText(EXT_MainActivity.this,e.toString(),Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onSuccess(Object o) {

            }
        });

Router的本质上是进行的方法调用,可以反依赖调用。就像工程中的app模块依赖example_lib模块,我们仍然可以在example_lib调用app中的方法。 当然正向调用也是可以的。

具体示例可以看example_lib中的EXT_MainActivity类调用appMainProvider类方法

PermissionUtil

将要进行的动作,需要某项危险权限时,我们需要先校验权限 PermissionUtil.hasSelfPermissions 如果有权限,则进行动作。 如果没有权限,校验是否需要提示 PermissionUtil.shouldShowRequestPermissionRationale;如果需要提示,则弹出提示框,用户点了允许之后再申请权限。如果不需要提示,则直接申请权限; 申请权限的结果有三种:

  1. 授权onGrant
  2. 禁止onDenied
  3. 禁止并不在提示 onNeverAskAgain

相关博客


TODO

  • @BindView 代替 findViewById
  • @ClickResponder 代替 setOnClickListener
  • @LongClickResponder 代替 setOnLongClickListener
  • @IntentValue 代替 getIntent().getXXX
  • @UriValue 代替 getQueryParameter
  • @BroadcastResponder 代替 registerReceiver
  • @RouterModule、@RouterPath 来进行反依赖传递调用
  • PermissionUtil 申请权限
You can’t perform that action at this time.