Это мой второй пост сегодня, так как исправление 1-го поста привело к другой проблеме, с которой я действительно борюсь. Я хочу использовать широковещательные передачи и намерен отправлять пакеты данных обратно из службы в пользовательский интерфейс. Мне удалось успешно привязать и запустить службу см. мой другой пост, если вам нужна история и код
Исключение нулевого указателя возникает при вызове sendBroadcast() внутри службы. Конструктор класса службы вызывается повторно после привязки пользовательского интерфейса к службе. Это происходит из другого класса, поэтому контекст нельзя легко использовать. Итак, я думаю, что sendBroadcast некуда идти :( Я подозреваю, что это моя проблема... повторный вызов конструктора службы после первоначальной привязки. У меня есть onDestroy, onPause и onResume, покрытые привязкой и отвязкой. Любые идеи или предложение было бы отличным, или, может быть, я просто ошибаюсь, есть ли другой способ?
EDIT Предыдущая проблема с привязкой теперь решена, и из-за того, что я новичок на форумах, небольшая задержка с принятием ответа... извините.
Диаграмма классов выглядит так (это портированный код C#)
Activity doBind (на Curve.class) ---> Activity запускает рабочий класс (не рассматривается как сервис) Comm.class с обработчиком для некоторых сообщений --> Comm запускает другой рабочий класс --> последний рабочий класс, наконец, вызывает новый Curve.класс.
Именно на этом последнем этапе Curve.class, где sendBroadcastReceiver() затем выдает ссылку нулевого указателя, потому что связыватель потерян. Я протестировал широковещательный приемник только с помощью простого таймера, отключающего рабочие классы между ними, и он отлично работает. Проблемы начинаются, когда Curve.class вызывается позже, ниже по иерархии, и связующее становится нулевым или «потерянным».
Я удалил все ссылки на связующее из Curve, кроме onBind(). Это может быть плохой идеей. Опять же, приведенный ниже код работает, если используется с простым таймером, запускаемым непосредственно из пользовательского интерфейса (без других рабочих классов).
Еще немного кода здесь: Сервис
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);
}
Активность теперь имеет этот код. doBind() вызывается после onCreate действия.
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 ???
EDIT Curve — это объект, который обрабатывает данные, константы и т. д., отправленные с внешней машины, и содержит обработанные данные в виде массивов. LogCat, конечно, существовал, я просто не смотрел в нужном месте, вот он
ARN/System.err(10505): java.lang.NullPointerException WARN/System.err(10505): at 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): at 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)
Вы также можете увидеть цепочку двух других рабочих классов, которые я использую. Конструктор Curve вызывается после связывания с CommMeasure. Так что это моя проблема. Нужно ли мне полностью менять настройку моей программы или есть другой способ обойти это?
ПОСЛЕДНИЕ РЕДАКТИРОВАНИЯ Этот код взят из C#, и Curve использовала обработчики событий для передачи данных. Я избавился от всех них (слушателей java) и использовал обработчик Android и широковещательный приемник. Было предложено передать 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..лол
Пользовательский интерфейс создает новый экземпляр ClientConnection, который, в свою очередь, создает новый экземпляр CommMeasure и, наконец, CommMeasure создает новый экземпляр Curve для доступа к Curve.addpoint. Я думаю, что этот поток и другой связанный 1 выходит за рамки простой проблемы с Android и подчеркивает трудности переноса кода. Например, любой разработчик .Net, читающий это, изучит некоторые особенности Android намного быстрее, чем я. Там также есть хороший рабочий код. Спасибо всем, кто помог, особенно Джастину Брайтфеллеру.