Java MainActivity中的Android BroadcastReceiver onReceive更新文本视图

Java MainActivity中的Android BroadcastReceiver onReceive更新文本视图,java,android,user-interface,background,textview,Java,Android,User Interface,Background,Textview,在MainActivity中,我有一个TextView:textV1。我在MainActivity中也有一个更新textview的方法: public void updateTheTextView(final String t) { MainActivity.this.runOnUiThread(new Runnable() { public void run() { TextView textV1 = (TextView) findViewByI

在MainActivity中,我有一个TextView:textV1。我在MainActivity中也有一个更新textview的方法:

public void updateTheTextView(final String t) {
    MainActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            TextView textV1 = (TextView) findViewById(R.id.textV1);
            textV1.setText(t);
        }
    });
}
在BroadcasrReceiver中,我需要在MainActivity中更新textV1中的文本

public class NotifAlarm extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
            // other things done here like notification

            // NEED TO UPDATE TEXTV1 IN MAINACTIVITY HERE
    }
}

如何做到这一点?BroadcastReceiver从服务运行。这个代码我无法更改。我可以从onReceive()访问和更改MainActivity中的textV1吗?我尝试过很多事情,但都失败了

MainActivity
中初始化
MainActivity
类的变量,如下所示

public class MainActivity extends Activity {
    private static MainActivity ins;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ins = this;     
    }

    public static MainActivity  getInstace(){
        return ins;
    }

    public void updateTheTextView(final String t) {
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                TextView textV1 = (TextView) findViewById(R.id.textV1);
                textV1.setText(t);
            }
        });
    }
}


public class NotifAlarm extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            MainActivity  .getInstace().updateTheTextView("String");
        } catch (Exception e) {

        }           
    }
}

创建类的实例,然后将值传递给更改TextView值的函数请遵循以下步骤: 在BroadcastReceiver中,重写onReceive方法,并根据需要粘贴这些行或更改主题

private Handler handler = new Handler(); // Handler used to execute code on the UI thread
// Post the UI updating code to our Handler
handler.post(new Runnable() {
    @Override
    public void run() {
    //Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
    YourActivityToUpdate.updateTheTextView(message);
    YourActivityToUpdateinst = YourActivityToUpdate.instance();
        if(inst != null)  { // your activity can be seen, and you can update it's context
        inst.updateTheTextView(message);
        }
    }
});
现在我们解释一下updateTheTextView和inst 请在活动更新课中粘贴这些行

private static SignUpVerify mInst;

public static SignUpVerify instance() {
        return mInst;
}
@Override
public void onStart() {
    super.onStart();
    mInst = this;
}

@Override
public void onStop() {
    super.onStop();
    mInst = null;
}
这是应该放在ActivityToUpdate类中的updateTheTextView方法

public void updateTheTextView(final String verifyCodeValue) {
                Log.i("verifyCodeValue", verifyCodeValue);
                YourTextViewToUpdate.setText(verifyCodeValue);
    }

我认为这是一个更好的方法,多亏了“kevin lynx”

如果有人在搜索这个精确的解决方案,但在Kotlin,请执行以下操作:

class MainActivity : AppCompatActivity() {

    companion object {
        var ins: MainActivity? = null
        fun getInstance(): MainActivity? {
            return ins
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ins = this
    }

    fun updateTheTextView(t: String) {
        this@MainActivity.runOnUiThread {
            val textV1 = findViewById<TextView>(R.id.textV1)
            textV1.text = t
        }
    }
}

class NotifAlarm : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        try {
            MainActivity.getInstance()?.updateTheTextView("The String")
        } catch (e: Exception) {

        }
    }
}
class MainActivity:AppCompatActivity(){
伴星{
变量ins:MainActivity?=null
有趣的getInstance():MainActivity{
返回
}
}
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
ins=这个
}
趣味updateTheTextView(t:String){
this@MainActivity.runOnUiThread {
val textV1=findViewById(R.id.textV1)
text v1.text=t
}
}
}
类NotifAlarm:BroadcastReceiver(){
覆盖接收(上下文:上下文?,意图:意图?){
试一试{
MainActivity.getInstance()?.updateTheTextView(“字符串”)
}捕获(e:例外){
}
}
}
#使用界面 处理这种情况的另一种方法是使用接口。我将描述这种方法的优点,但首先,让我们看看它是如何实现的

遵循以下步骤:
1)创建一个接口

public interface MyBroadcastListener{

    public void doSomething(String result);

}
2)在BroadCastReceiver中初始化侦听器

public class NotifAlarm extends BroadcastReceiver {

    private MyBroadcastListener listener;

    @Override
    public void onReceive(Context context, Intent intent) {
       
        listener = (MyBroadcastListener)context;

        // other things done here like notification

        // NUPDATE TEXTV1 IN MAINACTIVITY HERE
        listener.doSomething("Some Result");
    }
}
3)在活动中实现接口并重写方法

public YourActivity extends AppCompatActivity implements MyBroadcastListener{

    // Your Activity code 

    public void updateTheTextView(String t) {
        TextView textV1 = (TextView) findViewById(R.id.textV1);
        textV1.setText(t);
    }

    @Override
    public void doSomething(String result){
         updateTheTextView(result);          // Calling method from Interface
    }

 }
##使用界面的优点

  • 当您将BroadcastReceiver放在不同的文件中时
  • 解耦广播接收机
使用接口使BroadcastReceiver独立于任何 活动。假设将来您想使用这个广播接收器 使用另一个从BroadcastReceiver获取结果的活动 然后开始一个详细的活动。这完全是一个错误 不同的任务,但您将使用相同的广播接收器,而不使用 广播接收机内部的单个代码更改

怎么做?
在活动中实现接口并重写方法。就这样

public ListActivity extends AppCompatActivity implements MyBroadcastListener{

    // Your Activity code 

    public void startDetailActivity(String title) {
        Intent i = new Intent(ListActivity,this, DetailActivity.class);
        i.putExtra("Title", title);
        startActivity(i);
    }

    @Override
    public void doSomething(String result){
         startDetailActivity(String title);    // Calling method from Interface
    }

 }

在broadcastreceiver类中发送广播

public class mybroadcaster extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
    context.sendBroadcast(new Intent("updatetext"));
  }
}
在您的活动中,注册广播接收器并调用它,在
onReceive
上执行您的工作,然后在
onDestroy()中注销广播接收器


只需获取一个静态字符串,然后将此textview的结果存储在其中,并在此类中访问它。感谢您的回复。对不起,我不知道你的意思。你能解释一下吗?非常感谢您的帮助。在MainActivity中声明一个静态字符串变量,然后将textview的值存储在该字符串中,然后您可以在任何类中的任何位置使用该字符串。我认为您可以这样做,但我不确定,请试一试。谢谢,我可以使用静态字符串,这不会更改mainactivity中textview中的文本。我需要能够更改onreceive()的文本形式。GetInstance()在broadcastreceiver:MainActivity.GetInstance()中不起作用。updateTheTextView(“字符串”);不知道getinstancejust在MainActivity中创建了这个方法,我也更新了答案。你,InnocentKiller和ashish,太棒了!工作完美。非常感谢。将答案标记为“求解”,以便帮助其他人找到答案。
private static main导致活动泄漏的可怕想法在updateTheTextView函数中不起作用:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.view.Window$Callback android.view.Window.getCallback()”-这是我一直面临的问题。
public class MyActivity  extends Activity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    registerReceiver(broadcastReceiver, new IntentFilter("updatetext"));
}

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do your work here
    }
};

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(broadcastReceiver);
  }
}