Android Studio之Debug运行期代码植入的方法

所属分类: 软件编程 / Android 阅读数: 47
收藏 0 赞 0 分享

我们开发中经常使用IDE的Debug功能,使用最频繁的就是断点查看变量内容,这篇文章主要是介绍在Debug时很常用的一些功能,如Debug变量更新、动态代码植入等。

背景

看下面一段代码

@Data
@ToString
@AllArgsConstructor
public class User {
  private String name;
  private String sex;
}
public class Client {
  private static final String[] NAMES = {"美队", "浩克", "黑寡妇"};
  private static final List<User> USERS = Arrays.stream(NAMES)
      .map(name -> new User(name, "男"))
      .collect(Collectors.toList());

  public static void main(String[] args) {
    for (User user : USERS) {
      System.out.println(user);
    }
  }
}

我们直接运行这段代码,得到的输出如下

Client.User(name=美队, sex=男)
Client.User(name=浩克, sex=男)
Client.User(name=黑寡妇, sex=男)

接下来都会围绕这段代码进行说明

普通断点

开发过程中普通断点在Debug过程中使用的算是最频繁的,只要在代码处添加该类型的断点,在Debug模式下,一旦代码执行到改行,程序将进入挂起状态,此时我们能查看到当前的运行状态,如图

条件断点

当添加断点的方法会被多次执行到,而我们只希望程序在特定的一些特定的地方(如只有在当前的user是 黑寡妇 时)断下来,此时我们可以借助条件断点,如下

注意看一下 Condition 部分,此处需要返回一个 boolean 类型的值,该值就是为了告诉程序当执行到该行代码时是否进行断点,true表示进行断点,false反之。 上面只需要对 黑寡妇 进行断点,所以添加的 Condition"黑寡妇".equals(user.getName())

改变变量状态

有时需要对断点时的变量赋值操作,已更改此时变量的值,这时可以使用 Set Value 方式,如下

除了 Set Value ,还可以通过估值器进行改变值状态,如下

条件断点 + 代码植入

改变变量状态能够动态地设置变量值,条件断点可以控制断点是能在此处挂起,那将两者结合就能达到在程序不挂起的情况下进行动态代码植入的效果。

Condition 里插入的代码如下

if ("黑寡妇".equals(user.getName())) {
  user.setSex("女");
}
// 此处返回false为了告诉IDE在该断点出不对程序执行挂起操作
return false;

这就相当于提供了运行期代码的动态植入功能,而且可以通过 Enable/Disable 断点的状态来进行开启/关闭该部分动态代码是否执行。我们可以通过这种方式添加任何希望添加的代码,比如在每个user对象print之前添加自定一段print

应用场景

Debug期间动态植入的应用场景其实有很多的,对应Android端,有时候只需要改变一个变量,添加一行代码就需要重新run整个Project,需要花费整个compile和install的时间才能看出改动之后的效果,如果当前这次更改无效的话,甚至需要再次修改再次运行,而通过debug方式,可以直接对其进行操作。对于后端每次改动之后的重新部署也一样(不考虑动态部署的情况)。

以Android场景为例,如下的代码,接收一个 imageUrl 参数并加载出来

public class ImageActivity extends Activity {

  private static final String KEY_CONTENT = "imageUrl";

  public static void open(Context context, String content) {
    Intent intent = new Intent(context, ImageActivity.class);
    intent.putExtra(KEY_CONTENT, content);
    context.startActivity(intent);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ImageView imageView = findViewById(R.id.image);
    // 取出参数内容
    String imageUrl = getIntent().getStringExtra(KEY_CONTENT);
    Glide.with(this).load(imageUrl).into(imageView);
  }

}

未植入代码之前,跳转到当前页面是这样的

此时如果需要动态改变当前的 imageUrl 参数,可以进行Debug模式,并通过动态代码植入方式进行 imageUrl 变量的重赋值,如下

添加植入的复制代码之后,进入Debug模式,然后重新进入该页面,显示的图片便替换为修改后的了。

 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

使用ViewPager实现android软件使用向导功能实现步骤

现在的大部分android软件,都是使用说明,就是第一次使用该软件时,会出现向导,可以左右滑动,然后就进入应用的主界面了,下面我们就实现这个功能
收藏 0 赞 0 分享

android在异步任务中关闭Cursor的代码方法

android在异步任务中如何关闭Cursor?在我们开发应用的时候,很多时候会遇到这种问题,下面我们就看看代码如何实现
收藏 0 赞 0 分享

Android自定义桌面功能代码实现

android自定义桌面其实很简单,看一个例子就明白了
收藏 0 赞 0 分享

android将图片转换存到数据库再从数据库读取转换成图片实现代码

有时候我们想把图片存入到数据库中,尽管这不是一种明智的选择,但有时候还是不得以会用到,下面说说将图片转换成byte[]数组存入到数据库中去,并从数据库中取出来转换成图像显示出来
收藏 0 赞 0 分享

TextView显示系统时间(时钟功能带秒针变化

用System.currentTimeMillis()可以获取系统当前的时间,我们可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间,可以做一个时钟的功能
收藏 0 赞 0 分享

Android用ListView显示SDCard文件列表的小例子

本文简单实现了用ListView显示SDCard文件列表,目录的回退等功能暂不讨论,获取文件列表,files即为所选择目录下的所有文件列表
收藏 0 赞 0 分享

Android拦截外拨电话程序示例

这篇文章主要介绍了Android拦截外拨电话的示例,大家参考使用吧
收藏 0 赞 0 分享

通过Html网页调用本地安卓(android)app程序代码

如何使用html网页和本地app进行传递数据呢?经过研究,发现还是有方法的,总结了一下,大致有一下几种方式
收藏 0 赞 0 分享

android Textview文字监控(Textview使用方法)

以手机号充值为例,当用户输入最后一位数时候,进行汇率的变换,本文就实现类似这样的功能
收藏 0 赞 0 分享

Android ListView长按弹出菜单二种实现方式示例

这篇文章主要介绍了Android ListView长按弹出菜单的方法,大家参考实现
收藏 0 赞 0 分享
查看更多