如何在android中更改外部活动的按钮点击监听器?

问题描述

我有一个包含 classes.dex 的 apk。我没有apk源代码。我已经从 dex 文件(LoginActivity)加载了一个活动,并在 LoginActivity 中为 button1 实现了 onClicklistener。我通过以下代码成功加载 dex 文件并从 dex 文件开始活动:

DexClassLoader dex = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),mAppContext.getCacheDir().getPath(),null,loader);    
toasterClass = dex.loadClass("com.example.myapplication.ui.login.LoginActivity");
Intent intent = new Intent();
intent.setClass(getApplicationContext(),toasterClass);
setContentView(View.inflate(getApplicationContext(),R.layout.activity_login,null));
Button mAddTaskButton = (Button) findViewById(R.id.button2);
mAddTaskButton.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog aldlg = new AlertDialog.Builder(gLoginActivity.this).create();
                aldlg.setTitle("Login");
                aldlg.setMessage("You pressed Login Button");
                aldlg.setButton(AlertDialog.BUTTON_NEUTRAL,"OK",new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,int which) {
                                dialog.dismiss();
                            }
                        });
                aldlg.show();
            }
        });
startActivity(intent);

但是当我单击 button2 时,它没有显示警报对话框。我认为 android 正在阻止从活动之外更改 onClicklistener。这是对的吗? 对如何实现这一点有帮助吗?

解决方法

当你使用代码时:

Button mAddTaskButton = (Button) findViewById(R.id.button2)

这意味着您尝试在当前 Activity 实例中查找视图(与 this.findViewById 相同)-而不是来自 com.example.myapplication.ui.login.LoginActivity

我有两个想法可以解决您的问题:

  1. 使用应用程序/活动方法 registerActivityLifecycleCallbacks (link for activity)。 This callback 有方法 onActivityCreated 提供已创建活动的实例。在此方法中,您可以通过调用 activity.getComponentName().getClassName()(链接到 getComponentName 方法和 ComponentName class description )来获取 Activity 的名称。如果 onActivityCreated 方法提供的活动是 com.example.myapplication.ui.login.LoginActivity,那么您可以像在代码片段中一样将 OnClickListene 添加到按钮(只需使用对活动的引用来获取按钮):
Button mAddTaskButton = (Button) activity.findViewById(R.id.button2);
mAddTaskButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                      ...
            }
        });

小心 ActivityLifecycleCallback 因为它附加到应用程序生命周期(不是活动)并且不要从回调中捕获活动的内容以避免内存链接。

  1. 另一种解决方案 - 您可以尝试创建名为 com.example.myapplication.ui.login.LoginActivity 的“存根”活动,然后将其扩展为: public class MyLoginActivity extends LoginActivity。然后您可以覆盖 MyLoginActivity 的 onCreate 方法并执行您想要的操作(我的意思是为按钮 onClick 侦听器添加代码)。但是您不需要将此“存根” LoginActivity 构建到应用程序(apk)中,您应该将其添加为仅编译依赖项。我不知道如何用一个类来做,但我知道其他解决方案:您可以将 LoginActivity 放在单独的模块或库(aar/jar)并将库(模块)添加为 compileOnly dependency to your gradle file (like here)