Smali常见语法

1. 获取assets目录中的资源

android:

AssetManager am = getResources().getAssets();
try{
  InputStream is = am.open("xxxx.png");
}catch(IOException e){
}

smali:

invoke-virtual {p0}, Lcom/speedsoftware/rootexplorer/RootExplorer;->getResources()Landroid/content/res/Resources;
move-result-object vX
invoke-virtual {vX}, Landroid/content/res/Resources;->getAssets()Landroid/content/res/AssetManager;
move-result-object v0

2. new对象的语法

android:

this.pic_hd1 = new PicHandler();

smali:

new-instance v6,Lcom/qt/MainActivity$PicHandler;
move-object v9,v6
move-object v6,v9
move-object v7,v9
move-object v8,v0
invoke-direct {v7,v8},Lcom/qt/MainActivity$PicHandler;->(Lcom/qt/MainActivity;)V
iput-object v6,v5,Lcom/qt/MainActivity;->pic_hd1:Landroid/os/Handler;

3. 操作Fragment的语法 android.app.FragmentManager

android:

        // 显示调用父类
        FragmentManager fragmentManagerSuper = super.getFragmentManager();
        // 调用继承的方法,实际仍调用的是父类的
        FragmentManager fragmentManagerThis = this.getFragmentManager();
        // 开启fragmentTransaction事务
        FragmentTransaction fragmentTransaction = fragmentManagerSuper.beginTransaction();
        // 加载fragment布局
        Fragment fragment = fragmentManagerSuper.findFragmentById(R.layout.activity_main);
        // 加入fragmentTransaction中的fragment才可以调用show() hide()
        fragmentTransaction.add(fragment, "test");
        // 隐藏fragment
        fragmentTransaction.hide(fragment);
        // 显示fragment
        fragmentTransaction.show(fragment);
        // 提交后hide() show()才生效
        fragmentTransaction.commit();

smali:

    invoke-super {p0}, Landroid/support/v7/app/AppCompatActivity;->getFragmentManager()Landroid/app/FragmentManager;

    move-result-object v1

    .local v1, "fragmentManagerSuper":Landroid/app/FragmentManager;
    invoke-virtual {p0}, Ltop/nodcat/www/testlogindemo/MainActivity;->getFragmentManager()Landroid/app/FragmentManager;

    move-result-object v2

    .local v2, "fragmentManagerThis":Landroid/app/FragmentManager;
    invoke-virtual {v1}, Landroid/app/FragmentManager;->beginTransaction()Landroid/app/FragmentTransaction;

    move-result-object v3

    .local v3, "fragmentTransaction":Landroid/app/FragmentTransaction;
    invoke-virtual {v1, v0}, Landroid/app/FragmentManager;->findFragmentById(I)Landroid/app/Fragment;

    move-result-object v0

    .local v0, "fragment":Landroid/app/Fragment;
    const-string v4, "test"

    invoke-virtual {v3, v0, v4}, Landroid/app/FragmentTransaction;->add(Landroid/app/Fragment;Ljava/lang/String;)Landroid/app/FragmentTransaction;

    invoke-virtual {v3, v0}, Landroid/app/FragmentTransaction;->hide(Landroid/app/Fragment;)Landroid/app/FragmentTransaction;

    invoke-virtual {v3, v0}, Landroid/app/FragmentTransaction;->show(Landroid/app/Fragment;)Landroid/app/FragmentTransaction;

    invoke-virtual {v3}, Landroid/app/FragmentTransaction;->commit()I

4. 操作Fragment的语法 android.support.v4.app.FragmentManager

谷歌推荐使用android.support.v4包中的组件,因此比较新的app都会使用android.support.v4包中类。

java

        // 获取android.support.v4.app.FragmentManager
        FragmentManager fragmentManagerThis = this.getSupportFragmentManager();
        // 开启fragmentTransaction事务
        FragmentTransaction fragmentTransaction = fragmentManagerThis.beginTransaction();
        // 方式一:在Activity的layout.xml布局文件中静态添加fragment布局方式
//        // 加载布局文件
//        Fragment fragment = fragmentManagerThis.findFragmentById(R.layout.fragment_hide_features);
//        // 加入fragmentTransaction中的fragment才可以调用show() hide()
//        fragmentTransaction.add(fragment, "test");
        // 方式二:在Activity的.java文件中动态添加
        // 创建需要添加的Fragment :HideFeaturesFragment
        HideFeaturesFragment hideFeaturesFragment = new HideFeaturesFragment();
        // 将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.fragment_main, hideFeaturesFragment);
//        // 隐藏fragment
//        fragmentTransaction.hide(fragment);
//        // 显示fragment
//        fragmentTransaction.show(fragment);
        // 提交后hide() show()才生效
        fragmentTransaction.commit();

5. 按钮设置点击事件的语法

android:

btn_login = findViewById(R.id.button_login);
// 设置按钮点击事件
btn_login.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    ...
  }
});

smali:

const v1, 0x7f070023 # 按钮id

invoke-virtual {p0, v1}, Ltop/nodcat/www/testlogindemo/MainActivity;->findViewById(I)Landroid/view/View;

move-result-object v1

check-cast v1, Landroid/widget/Button; # 类型转换

iput-object v1, p0, Ltop/nodcat/www/testlogindemo/MainActivity;->btn_login:Landroid/widget/Button; # this.btn_login = v1

iget-object v1, p0, Ltop/nodcat/www/testlogindemo/MainActivity;->btn_login:Landroid/widget/Button;

new-instance v2, Ltop/nodcat/www/testlogindemo/MainActivity$1; # 匿名内部类 View.OnClickListener接口的匿名实现

invoke-direct {v2, p0}, Ltop/nodcat/www/testlogindemo/MainActivity$1;->(Ltop/nodcat/www/testlogindemo/MainActivity;)V # 构造函数

invoke-virtual {v1, v2}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V # 为按钮设置监听事件

6. 区分invoke-virtual、invoke-super

invoke-virtual表示调用继承的方法 this.method();
invoke-super表示直接调用父类的方法 super.method();
invoke-direct表示调用自身的方法或者某个对象构造方法
android:

this.login(username, pwd);

FragmentManager fragmentManagerSuper = super.getFragmentManager();

FragmentManager fragmentManagerThis = this.getFragmentManager();

smali:


7. Activity跳转的语法

android:

// 方法一:可以在Activity以及Fragment中调用该方法跳转到指定的Activity
this.startActivity(new Intent(this,PanelActivity.class));

// 方法二:在AndroidManifest.xml中配置
        
            
                
                
            
            
                
                
                
                
            
                
        
// 传入指定action动作的Intent后将自动匹配跳转的activity
this.startActivity(new Intent("android.intent.action.VIEW"));

smali:

# 方法二对应smali:
    new-instance v0, Landroid/content/Intent;
    const-string v1, "android.intent.action.VIEW"
    invoke-direct {v0, v1}, Landroid/content/Intent;->(Ljava/lang/String;)V # new Intent("android.intent.action.VIEW")
    invoke-virtual {p0, v0}, Ladmsdk/library/activity/AdDetailActivity;->startActivity(Landroid/content/Intent;)V # this.startActivity(v0); v0=new Intent("android.intent.action.VIEW")
    

8. 安卓动态设置控件布局属性的语法

android:

textview.setLayoutParams(layoutParams);

smail:

invoke-virtual {v0, v1}, Landroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V # v0=textview对象 v1为LayoutParams对象

9. 获取证书签名的语法

android:

/** 通过包管理器获得指定包名包含签名的包信息,PackageManager.GET_SIGNATURES的值为64,转换为16进制则为0x40 **/
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
/******* 通过返回的包信息获得签名数组 *******/
Signature[] signatures = packageInfo.signatures;
/******* 循环遍历签名数组拼接证书签名 *******/
return signatures[0].toCharsString();
/************** 得到证书签名 **************/

smali:

    iget-object v1, p0, Lcom/shuqi/app/ShuqiApplication$3;->val$context:Landroid/content/Context;

    invoke-virtual {v1}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v1

    const/16 v2, 0x40

    # 获取packageInfo对象
    invoke-virtual {v0, v1, v2}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;

    move-result-object v0
    # 得到packageInfo.signatures属性,该属性为Signature[] 数组
    iget-object v0, v0, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature;

    const/4 v1, 0x0
    # 获取数组中的第一个元素signatures[0]即Signature对象
    aget-object v0, v0, v1

10. 退出app的语法 — 方式一

android:

# 杀掉自己进程
android.os.Process.killProcess(android.os.Process.myPid());

smali:

# 获取进程ID
invoke-static {}, Landroid/os/Process;->myPid()I

move-result v0
# 杀死指定ID的进程
invoke-static {v0}, Landroid/os/Process;->killProcess(I)V

11. 退出app的语法 — 方式二

android:

System.exit(0);

smali:

const v0, 0
invoke-static {v0}, Ljava/lang/System;->exit(I)V

12.

你可能感兴趣的:(Smali常见语法)