这是我今天的第二篇文章,将第一篇文章引导到另一个我正在努力解决的问题。我想使用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的人
答案 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()来发送你的观点。这将阻止您在长时间运行的任务中要求引用该服务。