【问题标题】:Android BroadcastReceiver onReceive Update TextView in MainActivityAndroid BroadcastReceiver onReceive 更新MainActivity中的TextView
【发布时间】:2014-05-17 04:30:41
【问题描述】:

在 MainActivity 我有一个 TextView:textV1。我在 MainActivity 中也有一个更新该文本视图的方法:

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 吗?我尝试了很多事情,但都失败了。

【问题讨论】:

  • 只取一个静态字符串,然后将这个textview的结果存储在其中,并在这个类中访问它。
  • 感谢 InnocentKiller 的回复。抱歉,我不确定你的意思。你能解释一下吗?感谢您的帮助。
  • 在 MainActivity 中声明一个静态字符串变量,然后将 textview 的值存储在该字符串中,然后您可以在任何类中的任何位置使用该字符串。
  • 我认为你可以做到这一点,但我不确定,但请尝试一下。
  • 谢谢,但是我可以使用静态字符串,这不会改变 mainactivity 中 textview 中的文本。我需要能够更改文本形式 onreceive()。

标签: java android user-interface background textview


【解决方案1】:

在您的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) {

        }           
    }
}

【讨论】:

  • getInstace() 在广播接收器中不起作用: MainActivity .getInstace().updateTheTextView("String");不知道getinstance
  • 就在 MainActivity 创建这个方法,我也更新了答案。
  • 你,InnocentKiller 和 ashish,太棒了!完美运行。非常感谢。
  • 标记答案解决,以便帮助其他人找到答案。
  • private static MainActivity ins; 导致活动泄漏的糟糕想法
【解决方案2】:

#使用接口 处理这种情况的另一种方法是使用接口。我将描述这种方法的优点,但首先,让我们看看它是如何完成的。

按照以下步骤操作:
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)在Activity中实现接口并覆盖方法

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 与另一个从 BroadcastReceiver 获取结果的 Activity 并启动一个DetailActivity。这完全是一个 不同的任务,但您甚至会使用相同的 BroadcastReceiver BroadcastReceiver 中的单个代码更改。

怎么做?
在Activity中实现接口并重写方法。就是这样!

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
    }

 }

【讨论】:

    【解决方案3】:

    创建一个类的实例,然后将值传递给更改 TextView 值的函数,请按照以下步骤操作: 在您的 BroadcastReceiver overRide 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 请在 YourActivityToUpdate 类中粘贴这些行

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

    这是应该放在 YourActivityToUpdate 类中的 updateTheTextView 方法

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

    感谢"kevin-lynx"

    ,我认为这是一个更好的方法

    【讨论】:

      【解决方案4】:

      如果有人正在搜索这个确切的解决方案,但在 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) {
      
              }
          }
      }
      

      【讨论】:

      • 在 updateTheTextView 函数中不起作用:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'android.view.Window$Callback android.view.Window.getCallback()' -这是我一直面临的问题。
      【解决方案5】:

      在你的广播接收器类中发送广播

      public class mybroadcaster extends BroadcastReceiver{
      @Override
      public void onReceive(Context context, Intent intent) {
          context.sendBroadcast(new Intent("updatetext"));
        }
      }
      

      在您的活动中注册您的广播接收器并调用它,在onReceive 完成您的工作并在onDestroy() 取消注册广播器

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多