sendBroadcast(intent) дает исключение нулевого указателя

Это мой второй пост сегодня, так как исправление 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 намного быстрее, чем я. Там также есть хороший рабочий код. Спасибо всем, кто помог, особенно Джастину Брайтфеллеру.


person user960914    schedule 26.09.2011    source источник
comment
если кто-то успешно ответил на ваш первый пост, убедитесь, что вы не забыли принять ответ.   -  person slayton    schedule 26.09.2011
comment
Можете ли вы опубликовать трассировку стека исключения из logcat?   -  person slayton    schedule 26.09.2011
comment
Было бы очень полезно, если бы вы разместили весь свой код и четко и кратко объяснили, что именно вы пытаетесь сделать. Я не вижу указанный код sendBroadcast()   -  person Justin Breitfeller    schedule 26.09.2011
comment
К сожалению, нет трассировки стека для нулевого указателя из sendbroadcast.   -  person user960914    schedule 27.09.2011
comment
В logcat всегда должна быть трассировка стека, если происходит сбой. Вы там проверяли?   -  person Justin Breitfeller    schedule 27.09.2011
comment
Как ваша программа переходит от AddPoint к Curve.AddPoint? Откуда CommMeasure получает ссылку на CurveService.   -  person Justin Breitfeller    schedule 27.09.2011


Ответы (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

Наконец, если ваш конструктор вызывается дважды в вашей службе, вы неправильно привязываетесь к своей службе или, возможно, вы неожиданно отвязываетесь от нее и снова связываетесь с ней.

EDIT Из трассировки стека видно, что CommMeasure должна иметь ссылку на экземпляр Curve, который вы получаете в onServiceConnected.

РЕДАКТИРОВАТЬ 2 Если вы действительно хотите упростить свою жизнь, передайте getApplicationContext() в свой класс CommMeasure и просто appContext.sendBroadcast() из этого класса, чтобы отправить свою точку зрения. Это предотвратит необходимость ссылки на службу в вашей длительной задаче.

person Justin Breitfeller    schedule 26.09.2011
comment
Служба и привязка запускаются, а затем снова вызывается конструктор службы. Я думаю, что, к сожалению, все это нужно будет изменить. - person user960914; 27.09.2011
comment
Кажется, ты рядом. Что должно происходить в Curve? Что вы имеете в виду, когда говорите, что предыдущий рабочий класс, наконец, вызывает новый Curve.class. - person Justin Breitfeller; 27.09.2011
comment
После повторного прочтения ваших правок я хочу, чтобы вы никогда не создавали экземпляр Curve самостоятельно. ОС Android должна быть единственной, которая когда-либо создавала службу или деятельность. Если вы создаете экземпляр Curve, вы, скорее всего, получите NPE, потому что к сервису не привязан контекст. - person Justin Breitfeller; 27.09.2011
comment
Привет, Джастин, ты здесь, и это, очевидно, проблема. В C# это был просто рабочий класс, который использовал обработчики событий для отправки данных, но, похоже, здесь это не сработает :( - person user960914; 27.09.2011
comment
Ну, я не уверен, как вы используете свои обработчики событий, поэтому я не могу вам помочь. Вы регистрируете службу Curve с событием в рабочем элементе? Если это так, просто убедитесь, что вы передаете CurveService, который вы получаете от onServiceConnected. - person Justin Breitfeller; 27.09.2011
comment
Нет, он зарегистрирован только в пользовательском интерфейсе. Я избавился от всех обработчиков С# (слушателей Java) и пошел только с обработчиком Android и широковещательным приемником. Я добавлю 1 последнее редактирование - person user960914; 27.09.2011