我有一个PhoneStateLister
,我收到了大量数据,然后发送到服务器。
如果我用一个片段给听众打电话,那一切都很好,但是当我在服务中调用它时,我得到一个NullPointerException
。这是我的代码:
PhoneStateListener:
public class CarrierStateListener extends PhoneStateListener {
private Context context;
private TelephonyManager telephonyManager;
private String carrierName;
private int mSignalStrength = 0;
private int mCellTowerID = 0;
private int mCellTowerAreCode = 0;
private int mcc = 0;
private int mnc = 0;
public CarrierStateListener(Context context) {
this.context = context;
}
/**
* Get the Signal strength from the provider, each time there is an update
*/
@Override
public void onSignalStrengthsChanged(final SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation loc = (GsmCellLocation) telephonyManager.getCellLocation();
String networkOperator = telephonyManager.getNetworkOperator();
/** Retrieving the carrier name **/
carrierName = telephonyManager.getNetworkOperatorName();
UserInformation.getSingleton(context).setNetwork(carrierName);
/** Retrieving the RSSI value **/
mSignalStrength = signalStrength.getGsmSignalStrength();
mSignalStrength = (2 * mSignalStrength) - 113; // -> dBm
UserInformation.getSingleton(context).setRssi(String.valueOf(mSignalStrength));
/** Retrieve the cell tower id (CID) and the LAC (location area code) **/
mCellTowerID = loc.getCid();
mCellTowerAreCode = loc.getLac();
UserInformation.getSingleton(context).setCellId(String.valueOf(loc.getCid()));
/**tower mobile network code (mnc) and mobile country code (mcc) **/
if (networkOperator != null) {
mcc = Integer.parseInt(networkOperator.substring(0, 3));
mnc = Integer.parseInt(networkOperator.substring(3));
UserInformation.getSingleton(context).setMnc(String.valueOf(mnc));
UserInformation.getSingleton(context).setMcc(String.valueOf(mcc));
} else {
Toast.makeText(context, "Couldn't retrieve mnc and mcc because network operator is "
+ networkOperator, Toast.LENGTH_SHORT).show();
}
}
和我的服务:
public class SendDataService extends Service {
private static final String TAG = "SendDataService";
private Thread t;
private TelephonyManager telephonyManager;
private CarrierStateListener pslistener;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SendDataService");
wl.acquire();
t = new Thread() {
@Override
public void run() {
while (true) {
try {
Log.e(TAG, "sending data...");
//post request to send data
Thread.sleep(6000);
} catch (InterruptedException ie) {
}
}
}
};
t.start();
Log.e(TAG, "the SendDataService started");
return START_STICKY;
}
我在片段的onResume()中启动服务:
getActivity().startService(new Intent(getActivity(), SendDataService.class));
片段开始时...这是我得到的例外:
09-14 16:11:05.034 21697-21697/? E/CallDataService﹕ the SendDataService started
09-14 16:11:05.036 21697-21729/? E/CallDataService﹕ sending data...
09-14 16:11:05.037 21697-21729/? E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-2445
Process: xxxxxxxx, PID: 21697
java.lang.NullPointerException: Attempt to read from field
'android.os.MessageQueue android.os.Looper.mQueue' on a null object reference
at android.os.Handler.<init>(Handler.java:229)
at android.os.Handler.<init>(Handler.java:137)
at android.telephony.PhoneStateListener$1.<init>(PhoneStateListener.java:270)
at android.telephony.PhoneStateListener.<init>(PhoneStateListener.java:270)
at android.telephony.PhoneStateListener.<init>(PhoneStateListener.java:240)
at xxxxxxxxxxxxx.CarierStateListener.<init>(CarierStateListener.java:27)
at xxxxxxxxx.SendDataService.listenForEvents(SendDataService.java:96)
at xxxxxx.util.SendDataService.access$000(SendDataService.java:25)
at xxxxxxxxxx.util.SendDataService$1.run(SendDataService.java:53)
答案 0 :(得分:12)
这是一个消息队列问题,你必须在调用telephonyManager.listen之前初始化looper并在之后循环。
new Thread(new Runnable() {
@Override
public void run() {
quitLooper = false;
Looper.prepare();
tManager.listen(new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
lastSignalStrength = signalStrength;
if(quitLooper)
Looper.myLooper().quit();
}
}, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
Looper.loop();
}
}).start();
答案 1 :(得分:1)
我有同样的问题。崩溃发生在MyPhoneListener类的构造方法中,该方法扩展了PhoneStateLister。但它没有任何作用。所以我通过阅读PhoneStateLister
的源代码来搜索超构造方法PhoneStateListener.java:
public PhoneStateListener() {
this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper());
}
public PhoneStateListener(long subId, Looper looper) {
if (DBG) log("ctor: subId=" + subId + " looper=" + looper);
mSubId = subId;
mHandler = new Handler(looper) {
...........
};
}
Handler.java:
public Handler(Looper looper) {
this(looper, null, false);
}
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
崩溃发生在&#34; mQueue = looper.mQueue;&#34;。因为Thread t没有looper,所以looper为null。