【问题标题】:sendBroadcast(intent) gives a null pointer exceptionsendBroadcast(intent) 给出空指针异常
【发布时间】:2011-09-26 16:33:55
【问题描述】:

这是我今天的第二篇文章,因为修复第一篇文章会导致另一个我非常努力的问题。我想使用广播和意图将数据包从服务发送回 UI。我成功绑定并启动服务 see my other post if you want history and code

空指针异常出现在服务内部的 sendBroadcast() 上。 将 UI 绑定到服务之后,服务类确实有其构造函数被重新调用。这发生在另一个类中,因此 Context 不能轻易使用。所以我猜 sendBroadcast 无处可去:( 我怀疑这是我的问题...在初始绑定后重新调用服务构造函数。我有 onDestroy、onPause 和 onResume 覆盖绑定和解除绑定。 任何想法或建议都会很棒,或者我只是在解决这个问题,还有其他方法吗?

编辑 以前的绑定问题现在已经解决了,由于我是论坛的新手,所以在接受答案方面略有延迟......对不起。

类图是这样的(是移植的C#code)

Activity doBind(在 Curve.class 上)---> Activity 启动一个工作类(不被视为服务) Comm.class 带有一些通信的 Handler--> Comm 启动另一个工作类 --> 前一个工作类最终调用 new Curve.class。

这是最后一个阶段 Curve.class,sendBroadcastReceiver() 然后抛出一个空指针引用,因为绑定器丢失了。 我只用一个简单的计时器测试了广播接收器,它切断了中间的工人类,它工作正常。当稍后在层次结构中进一步调用 Curve.class 并且活页夹被清空或“丢失”时,问题就开始了。

我从 Curve 中删除了所有对活页夹的引用,除了 onBind()。这可能不是一个好主意。如果使用直接从 UI 启动的简单计时器(没有其他工作程序类),下面的代码仍然可以工作。

这里还有更多代码: 服务

    public class Curve extends Service
{
    private NewCurvePointEventArgs newpoint = null;
    private static final String TAG = "Curve";

    Intent intent;
    int counter = 0;


    @Override
    public void onCreate() {
        super.onCreate();   

    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        IBinder mBinder = new LocalBinder<Curve>(this);
        return mBinder;
    }
    @Override
    public void onStart(Intent intent, int startId) {

    }
    @Override
    public void onDestroy() {

    }
    public Curve(){

    }
    private void refreshintent(NewCurvePointEventArgs tmp)
    {
        ArrayList<String> thepoint = new ArrayList<String>();
        thepoint.add()//various things added here

         Bundle bundle = new Bundle();
            // add data to bundle
            bundle.putStringArrayList("New_Point", thepoint);

        intent = new Intent();
        intent.setAction(NEWCURVE_POINT);
        intent.putExtra("NEW_POINT", bundle

        sendBroadcast(intent);

    }

活动现在有这个代码。在活动的 onCreate 之后调用 doBind()。

        private BroadcastReceiver CurveReceiver  = new BroadcastReceiver(){

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Curve.NEWCURVE_POINT)) {
            displaynewpoint(intent); 

        }
    }
};
private ServiceConnection CurveServiceConncetion = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // TODO Auto-generated method stub

        CurveService = ((LocalBinder<Curve>) service).getService();

    }
    @Override
    public void onServiceDisconnected(ComponentName name) {

        // TODO Auto-generated method stub
        CurveService = null;
    }
};

@Override
public synchronized void onResume() {
    super.onResume();
    if(D) Log.e(TAG, "+ ON RESUME +");

}

@Override
public synchronized void onPause() {
    super.onPause();
    if(D) Log.e(TAG, "- ON PAUSE -");
}

@Override
public void onStop() {
    super.onStop();
    if(D) Log.e(TAG, "-- ON STOP --");
}

@Override
public void onDestroy() {
    super.onDestroy();

    if(D) Log.e(TAG, "--- ON DESTROY ---");

    unregisterReceiver(CurveReceiver);
    unbindService(CurveServiceConncetion); 
}
public  void doBind(){
    Boolean tmp;
    tmp = bindService(new Intent(this, Curve.class), CurveServiceConncetion, Context.BIND_AUTO_CREATE);//Context.BIND_AUTO_CREATE

    IntentFilter filter = new IntentFilter(Curve.NEWCURVE_POINT);  
    registerReceiver(CurveReceiver, filter);
}

对我来说这个问题是因为 Curve.class 在初始 doBind() 之后再次调用了它的构造函数。 当然必须有办法解决这个问题,否则我必须使用 Curve.class 中的代码将我的工作类加载到更接近 UI 的层次结构中???

编辑 曲线是一个对象,它处理从外部机器发送的数据、常量等,并将处理后的数据包含在数组中。 logCat 当然存在,我只是没找对地方

ARN/System.err(10505):java.lang.NullPointerException WARN/System.err(10505): 在 android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:271) WARN/System.err(10505):在 pi.droid.Core.Curve.refreshintent(Curve.java:206) WARN/System.err(10505): 在 pi.droid.Core.Curve.AddPoint(Curve.java:400) WARN/System.err(10505):在 pi.droid.Core.Comm.CommMeasure$CommMeasurement.AddPoint(CommMeasure.java:363) WARN/System.err(10505):在 pi.droid.Core.Comm.CommMeasure$GenericCommMeasurement.TryProcessData(CommMeasure.java:168) WARN/System.err(10505):在 pi.droid.Core.Comm.CommMeasure$CommMeasurement.ProcessData(CommMeasure.java:302) WARN/System.err(10505):在 pi.droid.Core.Comm.ClientConnection$timer_tick.run(ClientConnection.java:164) WARN/System.err(10505): 在 java.util.Timer$TimerImpl.run(Timer.java:289)

您还可以看到我使用的另外 2 个工人阶级的链条。 Curve 的构造函数在 CommMeasure 绑定后调用。 所以这是我的问题。 我需要完全改变我的程序设置方式还是有其他方法可以解决这个问题?

最终编辑 此代码来自 c#,Curve 使用事件处理程序来传递数据。我摆脱了所有这些(java监听器)并使用了android Handler和broadcastreceiver。 有人建议我应该传递 CurveService ,但这将是有问题的,因为 Curve 有多个构造函数。服务的无参数1,然后像这样的1

    public Curve(Unit XUnit, Unit YUnit)
    {           this.Title = "Curve";
        this.finished = false;
        this.XUnit = XUnit;
        this.YUnit = YUnit;
        this.YDirection = CurveDirection.Unspecified;

    }

所以实例化肯定会是 CurveService 的一个问题,它必须是这样的:public Curve(){} ?? 无论如何,非常感谢您的帮助和建议。

最终编辑 +1..lol

UI 创建一个新的 ClientConnection 实例,然后创建一个新的 CommMeasure 实例,最后 CommMeasure 创建一个新的 Curve 实例以访问 Curve.addpoint。 我认为这个线程和其他链接的 1 超越了一个简单的 android 问题,并突出了代码移植的困难。例如,任何 .Net 开发人员阅读本文都会比我更快地了解 android 的一些特性。那里也有很好的工作代码。 感谢所有帮助过的人,尤其是 Justin Breitfeller

【问题讨论】:

  • 如果有人成功回答了您的第一个帖子,请确保您记得接受回答。
  • 你能从 logcat 发布异常堆栈跟踪吗?
  • 如果您发布所有代码并清楚简洁地解释您正在尝试做什么,这可能会非常有帮助。我没有看到引用的 sendBroadcast() 代码
  • 不幸的是,sendbroadcast 的空指针没有堆栈跟踪
  • 如果发生崩溃,logcat 中应该始终有一个堆栈跟踪。你去那里查了吗?

标签: android service android-intent broadcastreceiver data-transfer


【解决方案1】:

您最好按照 Android APIDemos 中的示例进行操作。

要像您想使用的那样使用它的服务: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html

查看这个文件中的 Binding 类,看看有一个像你应该做的那样绑定的类: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html

最后,如果你的构造函数在你的服务上被调用了两次,你没有正确地绑定到你的服务,或者你正在解除绑定并意外地再次绑定到它。

编辑 从堆栈跟踪来看,CommMeasure 似乎需要引用您在 onServiceConnected 中收到的 Curve 实例。

编辑 2 如果您真的想让您的生活变得简单,请将 getApplicationContext() 传递给您的 CommMeasure 类,然后从该类中传递 appContext.sendBroadcast() 来传达您的观点。这将防止您在长期运行的任务中要求对服务的引用。

【讨论】:

  • 服务和绑定被启动,然后再次调用服务的构造函数。我认为不幸的是,这一切都需要改变。
  • 你似乎很亲密。曲线中应该发生什么?当你说“以前的工人阶级终于调用了新的 Curve.class”时,你是什么意思。
  • 重新阅读您的编辑后,我想让您永远不会自己实例化 Curve 的实例。 Android 操作系统应该是唯一可以创建服务或活动的操作系统。如果您正在创建 Curve 的实例,则很可能会获得 NPE,因为没有将上下文附加到服务。
  • 嗨,贾斯汀,你在这里,这显然是问题所在。在 C# 中,它只是一个使用事件处理程序来发送数据的工作类,但它似乎在这里不起作用:(
  • 好吧,我不确定您是如何使用事件处理程序的,所以我无法提供太多帮助。您是否正在通过工作项目上的事件注册 Curve 服务?如果是这样,只需确保传递从 onServiceConnected 获得的 CurveService。
猜你喜欢
  • 2014-09-06
  • 2014-07-19
  • 2017-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多