Android 开源框架之AndroidAnnotations快速入门

官方项目地址:github AA


简介

在浏览项目的首页之后,通过对比可以清楚的看到,相比android原生的开发方式,AA能够使我们的代码精简不少。省去了繁琐的控件查找、事件绑定,让我们专注业务处理。这仅仅只是它强大功能的一角。


AA的特性
  1. 依赖注入(DI),可以注入view,extra,资源,服务。方便我们编程,变相的减少了代码错误的可能性。
  2. 简化的线程模型。UI线程,background后台操作耗时联网请求。
  3. 事件绑定 非常方便的事件绑定机制,不再需要丑陋的匿名内部 listener类了。
  4. REST Client 依赖于spring rest,要求后端服务的接口是restful风格的。
  5. No Magic 不知道表达的是什么意思。AA的机制是使用的注解是编译注解,就是在程序编译的时候才编译解释,生成一个同当前类名带下划线的类,如MainActivity_ ,而不是使用反射,所以效率同原生开发方式。
Android studio中配置

需要在项目的build.gradle中进行加入一些配置(带注释的部分)

` buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.2'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4+'
`    }
}
allprojects {  //所有项目依赖的仓库地址,也可以配置maven,
//但是jcenter是专门为android定制提供的,比maven好,忘记在哪里看
//到的这句话了,自己的项目中配置了这个allprojects才会自动下载AA的依赖
    repositories {
        jcenter()
    }
}`

同时,模块下的buil.gradle文件也需要配置:

`apply plugin: 'com.android.application'
apply plugin: 'android-apt'
def AAVersion = '3.2+'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.sondon.mayi.hii"
        minSdkVersion 15
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
`
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.android.support:support-v4:22.1.1'
}
`
apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        // if you have multiple outputs (when using splits), you may want to have other index than 0
`
       ` // You can set optional annotation processing options here, like these commented options:`
     `   // logLevel `'INFO'
        `// logFile ` ' /var/log/aa.log '
`
    }
}`
`

排版有点丑,第一次使用markdown,还在摸索中。

例子

对于使用,一定要在清单文件中使用带下划线的类。如,MainActivity_
请注意看代码中的onPreExcute,doInback(),onPostExcute()三个,方法,提供了很好的UI,后台操作模型。
直接上例子吧。一下的代码,都是在同一个类中。

这里写代码片` @EActivity(R.layout.activity_login)`
`public class LoginActivity extends Activity implements `RestErrorHandler {`

    `private static final String TAG = LoginActivity.class.getSimpleName();`

    //可以这样使用,是因为id和变量名一样,不一样的话,需要自己绑定
    @ViewById
    EditText etUserName;

    @ViewById
    EditText etPassword;
    @ViewById
    CheckBox cbRememberPassword;
    @ViewById
    CheckBox cbAutoLogin;
    @ViewById
    Button btnLogin;

    //注入rest client
    @RestService
    MyRestClient mRestClient;
    //sharedpreferens的使用
    @Pref
    LoginPrefs_ mPrefs;

    private Dialog mloadingDialog;

    /**
     * 可以在这里 初始化 http
     */
    @AfterInject
    void afterInject() {

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setConnectTimeout(2*1000);
        mRestClient.getRestTemplate().setRequestFactory(requestFactory);

        mRestClient.setRestErrorHandler(this);
    }

    /**
     * 执行完控件绑定之后执行
     */
    @AfterViews
    void afterViews() {
        String username = mPrefs.username().get();
        String password = mPrefs.password().get();

        boolean isRmemberpassWord = mPrefs.isRmemberpassWord().get();
        boolean isAutoLogin = mPrefs.isAutoLogin().get();

        etUserName.setText(username);
        etPassword.setText(password);
        cbRememberPassword.setChecked(isRmemberpassWord);
        cbAutoLogin.setChecked(isAutoLogin);

        if (isAutoLogin) {
            doInBackground(username, password);
        }
        // TODO 为了方便测试
`//     btnLogin.setEnabled(true);
    }
    @Click(R.id.btnLogin)
    public void btnLogin(View v) {
        Log.d(TAG, "btnLogin()");
        if(!APKUtils.isNetWorkAvailable(getApplicationContext())){
          Toast.makeText(getApplicationContext(), "网络不可用", 1).show();
        }

        String username = etUserName.getText().toString().trim();
        String password = etPassword.getText().toString().trim();

        if (TextUtils.isEmpty(username)) {
            Toast.makeText(getApplicationContext(), "请输入用户名!", Toast.LENGTH_LONG).show();
            return;
        }

        if (TextUtils.isEmpty(password)) {
            Toast.makeText(getApplicationContext(),"请输入密码!", Toast.LENGTH_LONG).show();
            return;
        }

        doInBackground(username, password);

    }
    //后台执行耗时操作,不能在这里更新UI
    @Background
    public void doInBackground(String username, String password) {
        Log.d(TAG, "doInBackground()");
        Log.d(TAG, "doInBackground()  username :"+username);
        Log.d(TAG, "doInBackground()  password:"+password);
        onPreExecute();

        // TODO 测试 rest api
//       String result = mRestClient.getInfo();

        BaseRequest br =  CacheUtils.getBaseRequest(this);

        LoginRequest request = new LoginRequest();

        request.baseRequest = br;
        request.userName = username;
        request.password = password;
        Log.d(TAG, "doInBackground() request:" + request);

        String result =""; 
//      result = mRestClient.login(request);

        Log.d(TAG, "doInBackground() request DeviceType:" + br.deviceType);
        Log.d(TAG, "doInBackground() request CustomerId:" + br.customer_id);
        Log.d(TAG, "doInBackground() request DeviceID:" + br.deviceID);
        Log.d(TAG, "doInBackground() request rootUrl:" + mRestClient.getRootUrl());

        onPostExecute(result);
    }
    //UI 线程,可以在这里操作UI
    @UiThread
    public void onPreExecute() {
        Log.d(TAG, "onPreExecute()");
        mloadingDialog = CustomerProgressDialog.createLoadingDialog(
                LoginActivity.this, "正在登陆...");
        mloadingDialog.show();
    }

    @UiThread
    public void onPostExecute(String result) {

        Log.d(TAG, "onPostExecute()  result :"+result);
        mloadingDialog.dismiss();
//      if(result==null)
//          return;
        // 获取登陆结果,跳转到mainactivity

        MainActivity_.intent(LoginActivity.this).localUser(etUserName.getText().toString()).start();

        /* Intent intent =new Intent(LoginActivity.this ,MainActivity.class);
         startActivity(intent);*/

        //存储用户名
        mPrefs.username().put(etUserName.getText().toString().trim());

        boolean isRemenberPwd = cbRememberPassword.isChecked();
        boolean isAutoLogin = cbAutoLogin.isChecked();

        if(isRemenberPwd || isAutoLogin){
            mPrefs.password().put(etPassword.getText().toString().trim());
        }else{
            mPrefs.password().put(null);
        }
        mPrefs.isAutoLogin().put(isAutoLogin);
        mPrefs.isRmemberpassWord().put(isRemenberPwd);

        finish();

    }
    //TextView中的文字更改执行
    @TextChange({ R.id.etUserName, R.id.etPassword })
    public void textChanged() {
        if (TextUtils.isEmpty(etUserName.getText().toString())
                || TextUtils.isEmpty(etPassword.getText().toString())) {
            btnLogin.setEnabled(false);
        } else {
            btnLogin.setEnabled(true);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if(mloadingDialog!=null){
                mloadingDialog.dismiss();
            }
        }
        return false;
    }

    @UiThread
    @Override
    public void onRestClientExceptionThrown(RestClientException e) {
        // TODO Auto-generated method stub
        mloadingDialog.dismiss();
        e.printStackTrace();
        Toast.makeText(this, "访问失败 " , Toast.LENGTH_SHORT).show();
    }
}`
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值