贈送源碼:https://github.com/yugu88/MagicWX。
《最完整的Android逆向知識體系》
集成分爲了兩部分:
①僅僅在App主工程使用:
在App的 build.gradle 中添加如下代碼:版本號9之前的沒有適配AndroidX,工程遷移AndroidX時會報錯。
dependencies {
implementation 'com.jakewharton:butterknife:9.0.0-rc3'
// 必須要有,不然無法綁定點擊事件
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc3'
}
②如果在Library projects中使用:
在Project的 build.gradle 中添加如下代碼:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-rc3'
}
}
library的build.gradle中添加如下:
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
...
dependencies {
implementation 'com.jakewharton:butterknife:9.0.0-rc3'
// 必須要有,不然無法綁定點擊事件
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc3'
}
library中使用需要使用R2,如下:
class MainActivity extends Activity {
@BindView(R2.id.user)
EditText username;
@BindView(R2.id.pass)
EditText password;
}
ButterKnife 注意事項:
- 在Activity 類中綁定 :ButterKnife.bind(this);必須在setContentView();之後綁定;且父類bind綁定後,子類不需要再bind。
- 在非Activity 類(eg:Fragment、ViewHold)中綁定: ButterKnife.bind(this,view);這裏的this不能替換成getActivity()。
- 在Activity中不需要做解綁操作,在Fragment 中必須在onDestroyView()中做解綁操作。
- 使用ButterKnife修飾的方法和控件,不能用private or static 修飾,否則會報錯。錯誤: @BindView fields must not be private or static. (com.zyj.wifi.ButterknifeActivity.button1)
- setContentView()不能通過註解實現。(其他的有些註解框架可以)
- 使用Activity爲根視圖綁定任意對象時,如果你使用類似MVC的設計模式你可以在Activity 調用ButterKnife.bind(this, activity),來綁定Controller。
- 使用ButterKnife.bind(this,view)綁定一個view的子節點字段。如果你在子View的佈局裏或者自定義view的構造方法裏 使用了inflate,你可以立刻調用此方法。或者,從XML inflate來的自定義view類型可以在onFinishInflate回調方法中使用它。
在Activity中綁定ButterKnife:
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//綁定初始化ButterKnife 必須在setContentView之後調用
ButterKnife.bind(this);
}
}
在Fragment中綁定ButterKnife:
public class ButterknifeFragment extends Fragment{
private Unbinder unbinder;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
//返回一個Unbinder值(進行解綁),注意這裏的this不能使用getActivity()
unbinder = ButterKnife.bind(this, view);
return view;
}
/** * onDestroyView中進行解綁操作 */
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
在Adapter中綁定ButterKnife:
將ViewHolder加一個構造方法,在new ViewHolder的時候把view傳遞進去。使用ButterKnife.bind(this, view)進行綁定。
public class MyAdapter extends BaseAdapter {
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
view = inflater.inflate(R.layout.testlayout, parent, false);
// 將ViewHolder加一個構造方法,在new ViewHolder的時候把view傳遞進去
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.name.setText("Donkor");
holder.job.setText("Android");
// etc...
return view;
}
static class ViewHolder {
@BindView(R.id.title)
TextView name;
@BindView(R.id.job)
TextView job;
public ViewHolder(View view) {
// 使用ButterKnife.bind(this, view)進行綁定
ButterKnife.bind(this, view);
}
}
}
ButterKnife的基本使用
/**
* 主App工程使用如下
*/
@BindView(R.id.txt_tips)
TextView mTxtTips;
/**
* library工程使用如下
*/
@BindView( R2.id.button)
Button button;
// 就是R和R2的區別,因爲library中目前不能調用R文件了。
// 同時綁定多個
@BindViews({ R2.id.button1, R2.id.button2, R2.id.button3})
public List<Button> buttonList ;
//綁定資源文件中string字符串
@BindString(R2.string.app_name)
String str;
//綁定資源文件中string裏面array數組
@BindArray(R2.array.city)
String [] citys ;
//綁定Bitmap 資源
@BindBitmap( R2.mipmap.bm)
public Bitmap bitmap ;
//具體色值在color文件中
@BindColor( R2.color.colorAccent )
int black; //綁定一個顏色值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
buttonList.get( 0 ).setText( "hello 1 ");
buttonList.get( 1 ).setText( "hello 2 ");
buttonList.get( 2 ).setText( "hello 3 ");
button.setText( str );
button.setText(citys[0]);
imageView.setImageBitmap(bitmap);
button.setTextColor(black);
}
@OnClick(R2.id.button1 ) //給 button1 設置一個點擊事件
public void showToast(){
Toast.makeText(this, "is a click", Toast.LENGTH_SHORT).show();
}
@OnLongClick( R2.id.button1 ) //給 button1 設置一個長按事件
public boolean showToast2(){
Toast.makeText(this, "is a long click", Toast.LENGTH_SHORT).show();
return true ;
}
// 我們可以使用 Android studio 的 Butterknife 插件zelezny 快速生成
@OnClick({R.id.ll_product_name, R.id.ll_product_lilv, R.id.ll_product_qixian, R.id.ll_product_repayment_methods})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.ll_product_name:
System.out.print("我是點擊事件1");
break;
case R.id.ll_product_lilv:
System.out.print("我是點擊事件2");
break;
case R.id.ll_product_qixian:
System.out.print("我是點擊事件3");
break;
case R.id.ll_product_repayment_methods:
System.out.print("我是點擊事件4");
break;
}
}
更多註解
- @BindView—->綁定一個view;id爲一個view 變量
- @BindViews —-> 綁定多個view;id爲一個view的list變量
- @BindArray—-> 綁定string裏面array數組;@BindArray(R.array.city ) String[] citys ;
- @BindBitmap—->綁定圖片資源爲Bitmap;@BindBitmap( R.mipmap.wifi ) Bitmap bitmap;
- @BindBool —->綁定boolean值
- @BindColor —->綁定color;@BindColor(R.color.colorAccent) int black;
- @BindDimen —->綁定Dimen;@BindDimen(R.dimen.borth_width) int mBorderWidth;
- @BindDrawable —-> 綁定Drawable;@BindDrawable(R.drawable.test_pic) Drawable mTestPic;
- @BindFloat —->綁定float
- @BindInt —->綁定int
- @BindString —->綁定一個String id爲一個String變量;@BindString( R.string.app_name ) String meg;
更多事件
- @OnClick—->點擊事件
- @OnCheckedChanged —->選中,取消選中
- @OnEditorAction —->軟鍵盤的功能鍵
- @OnFocusChange —->焦點改變
- @OnItemClick item—->被點擊(注意這裏有坑,如果item裏面有Button等這些有點擊的控件事件的,需要設置這些控件屬性focusable爲false)
- @OnItemLongClick item—->長按(返回真可以攔截onItemClick)
- @OnItemSelected —->item被選擇事件
- @OnLongClick —->長按事件
- @OnPageChange —->頁面改變事件
- @OnTextChanged —->EditText裏面的文本變化事件
- @OnTouch —->觸摸事件
- @Optional —->選擇性注入,如果當前對象不存在,就會拋出一個異常,爲了壓制這個異常,可以在變量或者方法上加入一下註解,讓注入變成選擇性的,如果目標View存在,則注入, 不存在,則什麼事情都不做
ButterKnife的代碼混淆
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
Butterknife插件:zelezny
安裝完成插件後,會提示重啓AS。重啓完後,可以寫一個佈局並且新建一個代碼類測試下。
要注意的是,需要將光標移到setContentView(R.layout.acty_login),中的R.layout.acty_login,然後右鍵Generate就有了。
贈送源碼:https://github.com/yugu88/MagicWX。
《最完整的Android逆向知識體系》