Java Android:从其他类访问MainActivity函数

Java Android:从其他类访问MainActivity函数,java,android,class,Java,Android,Class,我在这里发现了许多类似的问题,但在我看来,所有这些问题都与我的略有不同 我有一个MainActivity类,可以调用在同一个类中定义的addInfo函数。还要考虑AddInFor函数访问Actuviy*主布局。 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onC

我在这里发现了许多类似的问题,但在我看来,所有这些问题都与我的略有不同

我有一个MainActivity类,可以调用在同一个类中定义的addInfo函数。还要考虑AddInFor函数访问Actuviy*主布局。
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);
    };   
}
现在我有了第二个类,它响应接收器来截获传入的SMS。此类需要调用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定义为static,那么内部代码是错误的。如果我将其保留为非静态,则第二个类不会看到addInfo

有人能给我指一下正确的方向吗


提前感谢

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

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

    public static MainActivity Instance;
一旦创建:

        Instance = this;
现在,无论你身在何处,请致电:

MainActivity.Instance.addInfo();

在您的案例中,最简单的解决方案之一是使用EventBus或类似的方法跨应用程序组件广播事件。因为当BroadcastReceiver接收到意图时,您的活动可能不活动,所以您的活动和接收者之间需要松散耦合

下面是一个使用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; }
}
//而不是直接调用活动

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.onNewIntent中处理数据。

创建接口:

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);
}

可能的重复将其作为单独的util类并重用。此外,您不能直接从其他Activity调用。在应用程序类中创建Activity对象以在每个Activity onCreate inti上设置currentactivity,并在顶部使对象为null,在SmsReceiver上,只需检查MainActivity的isInstance和not null。为什么不在实用程序类中使用该方法呢?我尝试创建一个实用程序类,但后来addInfo开始出现错误,因为findViewById使用的函数从未这样做过。通过保持对某个活动的静态引用,可以防止它被垃圾收集并导致内存泄漏。thumnb的一条规则是:除了应用程序上下文之外,永远不要对任何上下文(如活动、片段、对话框等)进行静态引用。如果应用程序超出了几个活动,这个解决方案将很难维护。yap这是一个有点复杂的解决方案,也许界面使它独立,你所指出的似乎是关键因素。当接收器被触发时,活动可能会停止!