【问题标题】:Error in Intent Service in AndroidAndroid 中的 Intent 服务错误
【发布时间】:2015-12-21 10:24:27
【问题描述】:

我正在尝试使用 IntentService 获取一些位置地址,但最终出现导致应用程序崩溃的错误。请帮帮我。

这里是堆栈跟踪:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.ResultReceiver.send(int, android.os.Bundle)' on a null object reference
        at com.example.ajender.sample2.FetchAddressIntentService.deliverResultToReceiver(FetchAddressIntentService.java:91)
        at com.example.ajender.sample2.FetchAddressIntentService.onHandleIntent(FetchAddressIntentService.java:81)
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.os.HandlerThread.run(HandlerThread.java:61)

这里是FetchAddressIntentService:

public class FetchAddressIntentService extends IntentService {
private static String TAG="Fetch-address-Service";
protected ResultReceiver mReceiver;

/**
 * Creates an IntentService.  Invoked by your subclass's constructor.
 *
 * @param name Used to name the worker thread, important only for debugging.
 */
public FetchAddressIntentService(String name) {
    super(name);
}
public FetchAddressIntentService(){
    super("FetchAddressIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
    String errorMessage = "";
    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
    Location location = intent.getParcelableExtra(
            Constants.LOCATION_DATA_EXTRA);
    mReceiver=intent.getParcelableExtra(Constants.RECEIVER);
    Log.e(TAG,"1-----");
    List<Address> addresses = null;

    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "service_not_available";
        Log.e(TAG, errorMessage, ioException);
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "invalid_lat_long_used";
        Log.e(TAG, errorMessage + ". " +
                "Latitude = " + location.getLatitude() +
                ", Longitude = " +
                location.getLongitude(), illegalArgumentException);
    }
    // Handle case where no address was found.
    if (addresses == null || addresses.size()  == 0) {
        if (errorMessage.isEmpty()) {
            errorMessage = "no_address_found";
            Log.e(TAG, errorMessage);
        }
        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
    } else {
        Address address = addresses.get(0);
        ArrayList<String> addressFragments = new ArrayList<String>();

        // Fetch the address lines using getAddressLine,
        // join them, and send them to the thread.
        for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
            addressFragments.add(address.getAddressLine(i));
        }
        Log.i(TAG, "address_found");
        deliverResultToReceiver(Constants.SUCCESS_RESULT,
                TextUtils.join(System.getProperty("line.separator"),
                        addressFragments));
    }

}

private void deliverResultToReceiver(int resultCode, String message) {
    Bundle bundle = new Bundle();
    bundle.putString(Constants.RESULT_DATA_KEY, message);
    Log.e(TAG, "2-----");
    mReceiver.send(resultCode, bundle);
    Log.e(TAG, "3-----");
}

此服务应该必须将带有结果接收器和结果代码的捆绑包发回,但没有发生......

【问题讨论】:

  • 您正试图通过null ResultReceiver 呼叫send()。除此之外,我们无法真正帮助您,因为我们无法看到com.example.ajender.sample2.FetchAddressIntentService 的来源。
  • 检查一次.....请@CommonsWare
  • mReceiver=intent.getParcelableExtra(Constants.RECEIVER); -- 这不起作用,因为你显然得到了null。确保您填写了这个额外的内容。

标签: java android android-intent android-studio stack-trace


【解决方案1】:

可以按照以下步骤解决该错误

  • 在 MainActivity 中

    • 添加公共AddressResultReceiver mResultReceiver;
    • mResultReceiver = new AddressResultReceiver(null)- 这将自动为主要活动类分配一个 ID。
  • 在 FetchAddressIntentService 中
    • 添加 mReceiver = intent.getParcelableExtra(Constants.RECEIVER);
    • 通过记录检查 mReceiver 是否为空。
    • 使用您当前的代码发送数据。 它应该工作。我就是这样解决它的。如果您有任何问题,请发表评论。

【讨论】:

    【解决方案2】:

    可能您没有正确初始化您的活动中的mResultReceiver,您应该将其传递给FetchAddressIntentService 意图:

    mResultReceiver = new AddressResultReceiver(new android.os.Handler());
    ..
    Intent intent = new Intent(this, FetchAddressIntentService.class);
    intent.putExtra(Constants.RECEIVER, mResultReceiver);
    ..
    startService(intent);
    

    【讨论】:

      【解决方案3】:

      IntentService 的情况是你有 三个组件 发挥作用:MainActivity(将调用意图服务),IntentService(负责处理意图)和最后一个ResultReceiver 在意图被处理(或操作)后接收结果。

      从Log 可以看出,您尚未初始化或为ResultReceiver mReceiver 分配任何值 您应该通过声明一个类来初始化 mResultReceiver,让我们将其称为 AddressResultReceiver,它扩展了 ResultReceiver,并有一个参数化构造函数,该构造函数接受单个参数作为 Handler 对象并覆盖 onReceiveResult() 方法,如下所示:

          AddressResultReceiver(Handler handler) {
              super(handler);
          }
      
          //Result from intent service
          @Override
          public void onReceiveResult(int resultCode, Bundle bundle) {
             ...
          }
      

      现在您已经成功获得了三个组件中的两个:MainActivity 用于启动意图请求,ResultReceiver 用于接收结果。现在让我们通过在项目层次结构中定义一个类并使用IntentService 扩展它并覆盖其方法onHandleIntent(Intent intent)() 来创建我们的IntentService:

      public class FetchAddressIntentService extends IntentService {
           public FetchAddressIntentService() {
              super("FetchAddressIntentService");
           }
           @Override
           protected void onHandleIntent(Intent intent) {...}
      }
      

      所以我们现在可以开始着手准备工作了。现在在您的MainActivity 中编写以下代码:

        //Initializing the reference with AddressResultReceiver object
        mResultReceiver = new AddressResultReceiver(new Handler());
        ...
        //Setting the IntentService to FetchAddressIntentService
        Intent intent = new Intent(this, FetchAddressIntentService.class);
      
        /*passing the receiver object to the service so as to let it know where to 
          publish results*/
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        ...
        //starting the service
        startService(intent);
      

      现在您的deliverResult(int, String) 将不再抛出NullPointerException。如需更多信息,请访问IntentService 和ResultReceiver。希望能帮助到你! :)

      【讨论】:

        【解决方案4】:

        在 Geocoder 之前的 protected void onHandleIntent (@Nullable Intent intent){} 中添加以下代码

            if (intent != null){
                String errorMessage ="";
                resultReceiver = intent.getParcelableExtra(Constants.RECEIVER);
                Location location = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA);
                if (location == null) {
                    return;
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-05
          相关资源
          最近更新 更多