Android 开源框架之AndroidAnnotations快速入门

来源:互联网 发布:男友一夜 知乎 编辑:程序博客网 时间:2024/05/20 19:14

官方项目地址: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();    }}`
0 0
原创粉丝点击