Soheyl Soheyl - 13 days ago 7
Android Question

Getting error on declaring broadcast receiver in different thread

i am trying to load a broadcast receiver in a different thread instead of my UI thread cause its slowing my app here is my broadcast receiver code :

private BroadcastReceiver battery_receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean isPresent = intent.getBooleanExtra("present", false);
//String technology = intent.getStringExtra("technology");
//int plugged = intent.getIntExtra("plugged", -1);
//int scale = intent.getIntExtra("scale", -1);
int health = intent.getIntExtra("health", 0);
//int status = intent.getIntExtra("status", 0);
//int rawlevel = intent.getIntExtra("level", -1);
float voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
if (voltage > 1000)
voltage=voltage / 1000f;
//int voltage = intent.getIntExtra("voltage", 0);
float temperature = intent.getIntExtra("temperature", 0);
if (temperature > 100) {
temperature = temperature / 10f;
}

//int level = 0;
Bundle bundle = intent.getExtras();
Log.i("BatteryLevel", bundle.toString());
if (isPresent) {

//String info = "Battery Level: " + level + "%\n";
//info += ("Technology: " + technology + "\n");
//info += ("Plugged: " + getPlugTypeString(plugged) + "\n");
//info += ("Health: " + getHealthString(health) + "\n");
//info += ("Status: " + getStatusString(status) + "\n");
//info += ("Voltage: " + voltage + "\n");
//info += ("Temperature: " + temperature + "\n");
setBatteryLevelText(String.valueOf(voltage) + " V");
setBatteryLevelText2(String.valueOf(temperature) + " °C");
setBatteryLevelText3(getHealthString(health));
} else {
setBatteryLevelText("Battery not present!!!");
}
}
};


and here is the code to load it on a thread

private void registerBatteryLevelReceiver() {
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Handler handler; // Handler for the separate Thread

HandlerThread handlerThread = new HandlerThread("MyNewThread");
handlerThread.start();
Looper looper = handlerThread.getLooper();
handler = new Handler(looper);
getApplicationContext().registerReceiver(battery_receiver, filter, null, handler);
//registerReceiver(battery_receiver, filter);
}


and all of them are before oncreate method but when i run it i get the error after few seconds after running the app with this error on logcat:

FATAL EXCEPTION: MyNewThread
Process: com.soheil.prolightfa, PID: 8880
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.BATTERY_CHANGED flg=0x60000010 bqHint=4 (has extras) } in com.soheil.prolightfa.MainActivity$1@fce2659
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1003)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8128)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1220)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:361)
at android.view.View.requestLayout(View.java:20085)
at android.widget.TableLayout.requestLayout(TableLayout.java:227)
at android.view.View.requestLayout(View.java:20085)
at android.view.View.requestLayout(View.java:20085)
at android.widget.TextView.setTypeface(TextView.java:3316)
at com.soheil.prolightfa.MainActivity.setBatteryLevelText(MainActivity.java:132)
at com.soheil.prolightfa.MainActivity.access$000(MainActivity.java:57)
at com.soheil.prolightfa.MainActivity$1.onReceive(MainActivity.java:101)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:993)

Answer

cause its slowing my app

That is very unlikely. Reading a few extras and updating a few TextView widgets will not take much time.

but when i run it i get the error after few seconds after running the app with this error on logcat

The error message is fairly self-explanatory:

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

You cannot modify the UI from a background thread, as you are doing. Remove the HandlerThread.