sendBroadcast(intent)给出一个空指针异常

时间:2011-09-26 16:33:55

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

这是我今天的第二篇文章,将第一篇文章引导到另一个我正在努力解决的问题。我想使用Broadcasts和intent将数据包从服务发送回UI。我设法绑定并成功启动服务 see my other post if you want history and code

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

修改 之前的绑定问题现在已经解决了,由于我是新来的论坛,接受答案时稍有延迟......抱歉。

类图就像这样(它是移植的C#代码)

Activity doBind(在Curve.class上)---> Activity启动一个worker类(不作为服务处理)Comm.class,带有一个用于某些通信的Handler - > Comm开始另一个工人阶级 - >前一个worker类最终调用了新的Curve.class。

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

除了onBind()之外,我从Curve中删除了所有关于binder的引用。这可能不是一个好主意。如果使用直接从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中

修改 Curve是一个对象,它处理从外部机器发送的数据,常量等,并在数组中包含已处理的数据。 logCat当然存在我只是在这里找不到正确的位置

ARN / System.err(10505):java.lang.NullPointerException WARN / System.err(10505):在android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:271) WARN / System.err(10505):at 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):at java.util.Timer $ TimerImpl.run(Timer.java:289)

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

最终编辑 此代码来自c#和Curve使用的事件处理程序来传递数据。我摆脱了所有这些(java听众)并使用了android Handler和broadcastreceiver。 有人建议我应该绕过CurveService,但这会有问题,因为Curve有多个构造函数。服务的无参数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的人

1 个答案:

答案 0 :(得分:0)

您最好的办法是按照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()来发送你的观点。这将阻止您在长时间运行的任务中要求引用该服务。