【问题标题】:Android: Access a MainActivity function from other class classAndroid:从其他类访问 MainActivity 函数
【发布时间】:2018-11-28 10:54:25
【问题描述】:

我在 SO 发现了许多类似的已回答问题,但在我看来,它们都与我的略有不同。

我的 MainActivity 类调用了在同一个类中定义的 addInfo() 函数。还要考虑 addInfo 函数访问 activity_main 布局。:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...
        String[] saInfoTxt = {"App Started"};
        addInfo("APP",saInfoTxt);
        ...

    }


    public void addInfo(String sType, String[] saInfoTxt) {

        Date dNow = Calendar.getInstance().getTime();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
        String sNow = dateFormat.format(dNow);

        LinearLayout layout = (LinearLayout) findViewById(R.id.info);
        String sInfoTxt =TextUtils.join("\n", saInfoTxt);
        sInfoTxt= sType + " " + sNow + "\n" + sInfoTxt;

        TextView txtInfo = new TextView(this);
        txtInfo.setText(sInfoTxt);
        txtInfo.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
        ((LinearLayout) layout).addView(txtInfo);
    };   
}

现在我有第二个类来响应接收器来拦截传入的短信。此类需要调用 MainActivity.addInfo() 函数,但我无法这样做:

public class SmsReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                // get sms objects
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus.length == 0) {
                    return;
                }
                // large message might be broken into many
                SmsMessage[] messages = new SmsMessage[pdus.length];
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    sb.append(messages[i].getMessageBody());
                }
                String sender = messages[0].getOriginatingAddress();
                String message = sb.toString();

                String[] saInfoTxt = {"Sender: " + sender,"Message: " + message};
                MainActivity.addInfo("SMS", saInfoTxt);

            }
        }
    }
}

如果我将 addInfo() 定义为静态,则内部代码有问题。如果我将其保留为非静态,则第二个类看不到 addInfo()

有人能指出正确的方向吗?

提前致谢

【问题讨论】:

  • 将其作为一个单独的 util 类并重用它。此外,您不能直接从其他 Activity 调用。
  • 在 Application 类中创建 Activity 对象以设置 currentactivity,在每个活动上 onCreate inti 和 onStop 使对象为 null,在 SmsReceiver 上只需检查 MainActivity 的 isInstance 而不是 null。
  • 为什么不在实用程序类中创建该方法?
  • 我试图创建一个实用程序类,但是 addInfo() 开始出现错误,因为“findViewById”使用了函数

标签: java android class


【解决方案1】:

如果是这种情况,您需要提取您的方法并创建一个新类,您可以在其中编写所有与业务相关的代码。当将您的业务相关代码隔离在其他类中时,您可以轻松地在每个活动中轻松调用或访问您的业务方法。或者你可以制作一些实用类。

【讨论】:

    【解决方案2】:

    要么将所有需要的代码从其他类移到一个类中,并使这个类成为静态的。如果这不是一个选项,请将您的活动设为单个实例:

        public static MainActivity Instance;
    

    创建时:

            Instance = this;
    

    现在无论你在哪里打电话:

    MainActivity.Instance.addInfo();
    

    【讨论】:

    • 永远不要这样做。通过保持对 Activity 的静态引用,您将防止它被垃圾收集并导致内存泄漏。作为一个经验法则:永远不要保留对任何上下文(如 Activity、Fragment、Dialogs 等)的静态引用,但应用程序上下文除外。
    【解决方案3】:

    在您的情况下,最简单的解决方案之一是使用 EventBus 或类似的方法来跨应用程序组件广播事件。由于在 BroadcastReceiver 接收意图时您的 Activity 可能不活跃,因此您需要在 Activity 和 Receiver 之间松散耦合。

    这是一个使用 EventBus 的示例实现,请确保首先将其包含在您的依赖项中 (https://github.com/greenrobot/EventBus):

    // Event.java

    class Event {
        private String text;
        private String[] array;
    
        public Event(String text, String[] array) {
            this.text = text;
            this.array = array;
        }
    
        public String getText() { return text; }
    
        public String[] getArray() { return array; }
    }
    

    // SmsReceiver.java(而不是直接调用activity)

    EventBus.getDefault().post(new Event("SMS", saInfoTxt));
    

    // MainActivity.java

    void onCreate() {
        ..
        EventBus.getDefault().register(this); // registers event listener
    }
    
    void onDestroy() {
        EventBus.getDefault().unregister(this); // unregister event listener (important!)
    }
    
    @Subscribe(threadMode = ThreadMode.MAIN) 
    void onEvent(Event event) {
        addInfo(event.getText(), event.getArray());
    }
    

    如果你想在没有 EventBus 或 RxJava 的情况下解决它,你也可以向你的 Activity 发送一个 Intent 并在 Activity.onNewIntent() 中处理数据。

    【讨论】:

    • 您指出的似乎是关键元素。当 Receiver 被触发时,Activity 可能会死掉!
    【解决方案4】:

    创建接口:

    public Interface CallBackInterface{
    void getData(String key, String[] arr);
    }
    

    关于应用类:

    public class BaseApplication extends Application
    {
    CallBackInterface event=null;
    ....// getter and setter 
     void setEvent(CallBackInterface event)
     {
      this.event=event;
     }
    }
    

    关于活动类:

    BaseApplication.getInstance.setEvent(new CallBackInterface()
    {
            @Override
            public void getData(String key,String[] arr) {
              //stuff to do....
            }
    });
    

    关于 SmsReceiver 类

    ....
    if(BaseApplication.getInstance.getEvent!=null){
    BaseApplication.getInstance.getEvent.sendData("SMS", saInfoTxt);
    }
    

    【讨论】:

    • 如果您的应用程序超出多个活动,此解决方案将变得非常难以维护。
    • yap 那是一个有点复杂的解决方案,也许接口让它独立
    猜你喜欢
    • 1970-01-01
    • 2013-10-02
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多