简体   繁体   English

Android:从其他类访问MainActivity函数

[英]Android: Access a MainActivity function from other class class

I found many similar answered issues here at SO but all of them seems to me slighty different from the mine. 我在SO上找到了许多类似的已回答问题,但在我看来,所有这些问题都与我的略有不同。

I have my MainActivity Class that recall the addInfo() function defined in the same class. 我有MainActivity类,该类可以调用在同一类中定义的addInfo()函数。 Consider also that addInfo function access the activity_ main Layout.: 还考虑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);
    };   
}

Now I have a second class that respond to a Receiver to intercept incoming SMS. 现在,我有了第二类,可以响应接收器来拦截传入的SMS。 This class needs to recall the MainActivity.addInfo() function but I'm not able to do so: 此类需要调用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);

            }
        }
    }
}

If I define the addInfo() as static then the internal code is faulty. 如果我将addInfo()定义为静态,则内部代码有问题。 If I leave it as non-static the second class doesn't see the addInfo() 如果我将其保留为非静态,则第二个类看不到addInfo()

Could someone point me to the right direction? 有人可以指出我正确的方向吗?

Thanks in advance 提前致谢

If this is the case, you need to extract your method and made a new class where you write you all business related code. 在这种情况下,您需要提取方法并创建一个新类,在其中编写所有与业务相关的代码。 When keep your business related code isolated in other class, then you are easily able to call or access your business method in every activity very easily. 当将与业务相关的代码隔离在其他类中时,您可以轻松地在每个活动中调用或访问您的业务方法。 Or you can make sort of utility class. 或者您可以制作一些实用程序类。

One of the simplest solutions in your case would be to use EventBus or similar to broadcast events across application components. 您遇到的最简单的解决方案之一就是使用EventBus或类似的方法在应用程序组件之间广播事件。 Since your Activity might not be alive when BroadcastReceiver is receiving an intent, you need loose coupling between your Activity and Receiver. 由于在BroadcastReceiver接收到意图时您的Activity可能不活跃,因此您需要在Activity和Receiver之间建立松散的耦合。

Here is an example implementation using EventBus, make sure to include it in your dependencies first ( https://github.com/greenrobot/EventBus ): 这是使用EventBus的示例实现,请确保首先将其包含在依赖项中( https://github.com/greenrobot/EventBus ):

// Event.java // 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 (instead of calling activity directly) // SmsReceiver.java(而不是直接调用活动)

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

// MainActivity.java // 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());
}

If you want to solve it without EventBus or RxJava, you could also send an Intent to your Activity and handle data in Activity.onNewIntent(). 如果要在没有EventBus或RxJava的情况下解决该问题,则还可以将一个Intent发送到Activity并处理Activity.onNewIntent()中的数据。

Create Interface: 创建界面:

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

On Application Class : 申请类别:

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

on Activity Class: 活动类别:

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

on SmsReceiver class 在SmsReceiver类上

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

Either move all code that is needed from other classes into one class and make this class static. 将所有需要的所有代码从其他类移到一个类中,并使该类静态。 if this is not an option make your activity be a single instance: 如果这不是一种选择,则使您的活动成为单个实例:

    public static MainActivity Instance;

OnCreate: 在OnCreate:

        Instance = this;

Now call whereever you are: 现在,无论您身在何处,都可以致电:

MainActivity.Instance.addInfo();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM