Android java.lang.RuntimeException: 接收广播 Intent 时出错
Android java.lang.RuntimeException: Error receiving broadcast Intent
我的应用程序一启动就崩溃了,我不明白为什么。我有一个 Service
用作计时器来计算自计时器启动以来的秒数,然后将其传递回我的 MainActivity
。
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BroadcastTest";
private Intent intent;
private Chronometer timer;
private Button start;
private Button stop;
private EditText hourlyRate;
private TextView money;
private long timeWhenStopped = 0;
private double moneyEarned;
private double secondsRate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer = (Chronometer) findViewById(R.id.chronometer);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
hourlyRate = (EditText) findViewById(R.id.hourlyRate);
money = (TextView) findViewById(R.id.money);
intent = new Intent(this, Timer.class);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(new Intent(MainActivity.this, Timer.class));
timer.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
timer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timeWhenStopped = timer.getBase() - SystemClock.elapsedRealtime();
timer.stop();
}
});
timer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener()
{
@Override
public void onChronometerTick(Chronometer chronometer){
long timeElapsed = SystemClock.elapsedRealtime() - timer.getBase();
int seconds = (int) timeElapsed / 1000;
double hrlyRate = Double.parseDouble(hourlyRate.getText().toString());
secondsRate = (hrlyRate / 60) / 60;
moneyEarned = secondsRate * seconds;
double displayMoney = Math.round(moneyEarned * 100.0)/100.0;
Log.d("hours",Long.toString(seconds));
money.setText("$"+Double.toString(displayMoney));
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
@Override
public void onResume() {
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(Timer.BROADCAST_ACTION));
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent) {
String counter = intent.getStringExtra("counter");
Log.d("SERVICE_SECONDS", counter);
}
}
Timer.java:
public class Timer extends Service {
private static final String TAG = "BroadcastService";
public static final String BROADCAST_ACTION = "b.calvin.com.dirtymoney";
private final Handler handler = new Handler();
Intent intent;
int counter = 0;
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
countSeconds();
handler.postDelayed(this, 1000); // 1 second
}
};
@Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 0); // 1 second
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void countSeconds() {
Log.d(TAG, Integer.toString(++counter));
sendBroadcast(intent);
}
}
错误:
FATAL EXCEPTION: main
Process: b.calvin.com.dirtymoney, PID: 3348
java.lang.RuntimeException: Error receiving broadcast Intent { act=b.calvin.com.dirtymoney flg=0x10 } in b.calvin.com.dirtymoney.MainActivity@bf337ff
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:891)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:139)
at b.calvin.com.dirtymoney.MainActivity.updateUI(MainActivity.java:113)
at b.calvin.com.dirtymoney.MainActivity.access0(MainActivity.java:20)
at b.calvin.com.dirtymoney.MainActivity.onReceive(MainActivity.java:93)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
您似乎忘记将 counter
变量放入 Intent
,因此您将 null
作为消息传递给 Log.d()
,结果是 NullPointerException
.
像这样的东西应该可以工作:
private void countSeconds() {
Log.d(TAG, Integer.toString(++counter));
Intent counterIntent = new Intent(BROADCAST_ACTION);
counterIntent.putExtra("counter", counter);
sendBroadcast(counterIntent);
}
此外,计数器是一个 int
,因此您应该调用 getIntExtra()
而不是 getStringExtra()
:
private void updateUI(Intent intent) {
int counter = intent.getIntExtra("counter");
Log.d("SERVICE_SECONDS", Integer.toString(counter));
}
我的应用程序一启动就崩溃了,我不明白为什么。我有一个 Service
用作计时器来计算自计时器启动以来的秒数,然后将其传递回我的 MainActivity
。
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BroadcastTest";
private Intent intent;
private Chronometer timer;
private Button start;
private Button stop;
private EditText hourlyRate;
private TextView money;
private long timeWhenStopped = 0;
private double moneyEarned;
private double secondsRate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer = (Chronometer) findViewById(R.id.chronometer);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
hourlyRate = (EditText) findViewById(R.id.hourlyRate);
money = (TextView) findViewById(R.id.money);
intent = new Intent(this, Timer.class);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(new Intent(MainActivity.this, Timer.class));
timer.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
timer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timeWhenStopped = timer.getBase() - SystemClock.elapsedRealtime();
timer.stop();
}
});
timer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener()
{
@Override
public void onChronometerTick(Chronometer chronometer){
long timeElapsed = SystemClock.elapsedRealtime() - timer.getBase();
int seconds = (int) timeElapsed / 1000;
double hrlyRate = Double.parseDouble(hourlyRate.getText().toString());
secondsRate = (hrlyRate / 60) / 60;
moneyEarned = secondsRate * seconds;
double displayMoney = Math.round(moneyEarned * 100.0)/100.0;
Log.d("hours",Long.toString(seconds));
money.setText("$"+Double.toString(displayMoney));
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
@Override
public void onResume() {
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(Timer.BROADCAST_ACTION));
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent) {
String counter = intent.getStringExtra("counter");
Log.d("SERVICE_SECONDS", counter);
}
}
Timer.java:
public class Timer extends Service {
private static final String TAG = "BroadcastService";
public static final String BROADCAST_ACTION = "b.calvin.com.dirtymoney";
private final Handler handler = new Handler();
Intent intent;
int counter = 0;
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
countSeconds();
handler.postDelayed(this, 1000); // 1 second
}
};
@Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 0); // 1 second
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void countSeconds() {
Log.d(TAG, Integer.toString(++counter));
sendBroadcast(intent);
}
}
错误:
FATAL EXCEPTION: main
Process: b.calvin.com.dirtymoney, PID: 3348
java.lang.RuntimeException: Error receiving broadcast Intent { act=b.calvin.com.dirtymoney flg=0x10 } in b.calvin.com.dirtymoney.MainActivity@bf337ff
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:891)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:139)
at b.calvin.com.dirtymoney.MainActivity.updateUI(MainActivity.java:113)
at b.calvin.com.dirtymoney.MainActivity.access0(MainActivity.java:20)
at b.calvin.com.dirtymoney.MainActivity.onReceive(MainActivity.java:93)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
您似乎忘记将 counter
变量放入 Intent
,因此您将 null
作为消息传递给 Log.d()
,结果是 NullPointerException
.
像这样的东西应该可以工作:
private void countSeconds() {
Log.d(TAG, Integer.toString(++counter));
Intent counterIntent = new Intent(BROADCAST_ACTION);
counterIntent.putExtra("counter", counter);
sendBroadcast(counterIntent);
}
此外,计数器是一个 int
,因此您应该调用 getIntExtra()
而不是 getStringExtra()
:
private void updateUI(Intent intent) {
int counter = intent.getIntExtra("counter");
Log.d("SERVICE_SECONDS", Integer.toString(counter));
}