When I use this code:
@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));
}
I get an error when trying to cast the context to MainActivity
.
Here is the error / stack trace:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jordanbleu.lab8chronservjordanbleu, PID: 22693 java.lang.RuntimeException: Error receiving broadcast Intent { act=com.example.jordanbleu.lab8chronservjordanbleu.MY_TIME_TICK flg=0x10 } in com.example.jordanbleu.lab8chronservjordanbleu.ChronometerReceiver@d9365fe at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1132) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.jordanbleu.lab8chronservjordanbleu.MainActivity at com.example.jordanbleu.lab8chronservjordanble u.ChronometerReceiver.onReceive(ChronometerReceiver.java:41) at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1122) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
So I have a MainActivity
, which starts a service. The service creates a new thread, and this thread constantly created implicit intents which are handled by a BroadcastReceiver
. This broadcast receiver will update a clock, and update a TextView
in the layout with the updated time. But when I try to get access to the findViewByID
via the context parameter, I get the error above.
Initialize your TextView
inside the onCreate
function of your Activity
.
TextView tv = (TextView) findViewById(R.id.txtChron);
Then in your onReceive
function
@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));
}
Your error is:
java.lang.ClassCastException: android.app.Application cannot be cast to com.example.jordanbleu.lab8chronservjordanbleu.MainActivity
This means "Context context" is Application, not the MainActivity.
My suggestion is, inflate your TextView in OnCreate.
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));
}
You may also use an interface. This way you will not have to access The UI element in the BroadcastReceiver.
1) Create an interface:
interface ReceiverListener {
public void doSomething(String arg1, String arg2);
}
2) Instantiate the Listener in your 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) Implement the interface in Your Activity and override the method
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);
}
}
If you want to see the advantage of using an interface in this case, READ THIS
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.