【问题标题】:How to get access to the MainActivity findViewById from inside a Broadcast Receiver onReceive method?如何从广播接收器 onReceive 方法中访问 MainActivity findViewById?
【发布时间】:2017-04-29 06:46:19
【问题描述】:

当我使用这段代码时:

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

    seconds += 0.1;

    if (seconds > 59.9) {
        seconds=0;
        minutes++;
    }

    TextView tv = (TextView)((MainActivity)context).findViewById(R.id.txtChron);
    tv.setText (String.valueOf(minutes) + ":" + String.valueOf(seconds));
}

尝试将上下文转换为 MainActivity 时出现错误。

这是错误/堆栈跟踪:

E/AndroidRuntime:致命异常:主进程: com.example.jordanbleu.lab8chronservjordanbleu,PID:22693 java.lang.RuntimeException:接收广播意图时出错{ act=com.example.jordanbleu.lab8chronservjordanbleu.MY_TIME_TICK flg=0x10 } 在 com.example.jordanbleu.lab8chronservjordanbleu.ChronometerReceiver@d9365fe 在 android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1132) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6119) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 引起 by: java.lang.ClassCastException: android.app.Application 不能 转换为 com.example.jordanbleu.lab8chronservjordanbleu.MainActivity 在 com.example.jordanbleu.lab8chronservjordanbleu.ChronometerReceiver.onReceive(ChronometerReceiver.java:41) 在 android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1122) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6119) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

所以我有一个MainActivity,它启动了一项服务。该服务创建一个新线程,该线程不断创建由BroadcastReceiver 处理的隐式意图。此广播接收器将更新时钟,并使用更新的时间更新布局中的TextView。但是当我尝试通过 context 参数访问findViewByID 时,我得到了上面的错误。

【问题讨论】:

    标签: java android android-intent broadcastreceiver android-service


    【解决方案1】:

    ActivityonCreate 函数中初始化TextView

    TextView tv = (TextView) findViewById(R.id.txtChron);
    

    然后在你的onReceive 函数中

    @Override
    public void onReceive(Context context, Intent intent) {
        seconds += 0.1;
        if (seconds > 59.9) {
            seconds=0;
            minutes++;
        }
    
        tv.setText(String.valueOf(minutes) + ":" + String.valueOf(seconds));
    }
    

    【讨论】:

      【解决方案2】:

      你的错误是:

      java.lang.ClassCastException: android.app.Application 无法转换为 com.example.jordanbleu.lab8chronservjordanbleu.MainActivity

      这意味着“上下文上下文”是应用程序,而不是 MainActivity。

      我的建议是,在 OnCreate 中为您的 TextView 充气。

      TextView tv;
      
      @Override
      public void onCreate(Bundle savedInstanceState) {
          tv = (TextView) findViewById(R.id.txtChron); // This!
      ...
      }
      
      @Override
      public void onReceive(Context context, Intent intent) {
      
          seconds += 0.1;
      
          if (seconds > 59.9) {
              seconds=0;
              minutes++;
          }
      
          tv.setText (String.valueOf(minutes) + ":" + String.valueOf(seconds));
      }
      

      【讨论】:

        【解决方案3】:

        您也可以使用接口。这样您就不必访问 BroadcastReceiver 中的 UI 元素。

        1) 创建界面:

        interface ReceiverListener {
            public void doSomething(String arg1, String arg2);
        }
        

        2) 在您的 BroadcastReceiver 中实例化监听器

        public class YourBroadCastReceiver extends BroadCastReceiver{
        
            private ReceiverListener listener;
        
            @Override
            public void onReceive(Context context, Intent intent) {
        
                listener = (ReceiverListener)context;  // Initialize listener 
        
                // Your logic 
                String minutes = //get it
                String seconds = // get it
        
               listener.doSomething(minutes,seconds); 
        
            }
        
        }
        

        3) 在你的Activity中实现接口并覆盖方法

        public YourActivity extends AppcompatActivity implements ReceiverListener{
        
             // Activity related code
            TextView tv;
        
            public void updateUI(String minutes,String seconds){
                tv.setText (minutes + ":" + seconds);
            }
        
        
            @Override 
            public void doSomething(String arg1, String arg2){
                updateUI(arg1,arg2);
            }
        
        }
        

        相关链接:

        如果你想看看在这种情况下使用接口的优势,READ THIS

        【讨论】:

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