2016-03-30 4 views
1

私はサービスに接続していて、その中のオブジェクトにアクセスするAndroidアプリケーションを開発中です。 1つのクラスに対して同じメカニズムが働いていて、NPEで他のクラスでは失敗しています。私はなぜ、何がうまくいかないのか分からない。どんな助けもいいだろう。Android:サービスから取得したオブジェクトもバインドサービス後もnullです

エラーログ:

java.lang.RuntimeException: Unable to start activity ComponentInfo 
    {mycompany.notes/mycompany.notes.Activity.ChatMessagesActivity}: java.lang.NullPointerException: Attempt to read from field 'org.cometd.client.BayeuxClient mycompany.notes.Activity.ConsoleChatClient.client' on a null object reference 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
    at android.app.ActivityThread.-wrap11(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Caused by: java.lang.NullPointerException: Attempt to read from field 'org.cometd.client.BayeuxClient mycompany.notes.Activity.ConsoleChatClient.client' on a null object reference 
    at mycompany.notes.Activity.ChatMessagesActivity.onCreate(ChatMessagesActivity.java:177) 
    at android.app.Activity.performCreate(Activity.java:6237) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 

サービスコード:

public class ConsoleChatClient extends Service { 

    private final IBinder mBinder = new LocalBinder(); 
    BayeuxClient client; 
    HttpClient httpClient = StaticRestTemplate.getHttpClient(); 
    String defaultURL = StaticRestTemplate.baseURL + "/cometd"; 


    public class LocalBinder extends Binder { 
     ConsoleChatClient getService() { 
      // Return this instance of LocalService so clients can call public methods 
      return ConsoleChatClient.this; 
     } 
    } 

    private void connectionEstablished() { 
     System.err.printf("system: Connection to Server Opened%n"); 

    } 

    private void connectionClosed() { 
     System.err.printf("system: Connection to Server Closed%n"); 
    } 

    private void connectionBroken() { 
     System.err.printf("system: Connection to Server Broken%n"); 
    } 

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

    @Override 
    public IBinder onBind(Intent intent) { 
     performConnection(); 
     return mBinder; 

    } 



private void performConnection() { 
     try { 
      httpClient.start(); 
      ClientTransport clientTransport = new LongPollingTransport(null, httpClient); 
      bayeuxClient = new BayeuxClient(defaultURL, clientTransport); 
      // Below for use with Spring-Security post-login. 
      bayeuxClient.putCookie(new HttpCookie("JSESSIONID", StaticRestTemplate.getJsessionid())); 
      bayeuxClient.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener()); 
      bayeuxClient.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener()); 
      bayeuxClient.handshake(); 
      StaticRestTemplate.setClient(bayeuxClient); 
      StaticRestTemplate.setHttpClient(httpClient); 
      boolean success = bayeuxClient.waitFor(2000, BayeuxClient.State.CONNECTED); 
      if (!success) { 
       System.err.printf("Could not handshake with server at %s%n", defaultURL); 
      }else { 
       System.err.printf("Handhskare complete"); 
      } 

     } catch (Exception ignored) {} 
    } 
    } 

ChatMessagesActivity.java:

public class ChatMessagesActivity extends ApplicationDrawerLoader { 

    HttpClient httpClient; 
    ConsoleChatClient consoleChatClient; 
    boolean mBound = false; 

    private ChatListener chatListener = new ChatListener(); 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     Intent intent = new Intent(this, ConsoleChatClient.class); 
     bindService(intent, mConnection, Context.BIND_IMPORTANT); 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, 
             IBinder service) { 
      ConsoleChatClient.LocalBinder binder = (ConsoleChatClient.LocalBinder) service; 
      consoleChatClient = binder.getService(); 
      mBound = true; 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      mBound = false; 
     } 
    }; 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     // Unbind from the service 
     if (mBound) { 
      unbindService(mConnection); 
      mBound = false; 

      if (conversationId != 0) { 
       consoleChatClient.client.getChannel("/person/" + conversationId).unsubscribe(); 
      } 

      if (groupAccountId != 0) { 
       consoleChatClient.client.getChannel("/chat/" + conversationId).unsubscribe(); 
      } 
     } 
    } 



    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat_messages); 

    try { 

      Intent intent = new Intent(this, ConsoleChatClient.class); 
      startService(intent); 
      httpClient = consoleChatClient.httpClient; 
     } catch (Exception ignored) { 
     } 

// Below code crashes at consoleChatClient.client 
if (conversationId != 0) { 
      consoleChatClient.client.getChannel("/person/" + conversationId).subscribe(chatListener); 
     } 

     if (groupAccountId != 0) { 
      consoleChatClient.client.getChannel("/chat/" + conversationId).subscribe(chatListener); 
     } 
} 

だから、私はそれが一つのクラスに動作することを間違って何をやっている、と他にはない。助けてください。ありがとうございました。

+0

? –

+0

'httpClient = consoleChatClient.httpClient;'ここで 'consoleChatClient'はnullです – pskink

+0

@pskink:実際には、httpClientはnullではなく、BayeuxClientはnullです。それが私を混乱させている、私はそれを確認した。 –

答えて

2

startService()の直後にbindService()を呼び出します。これは、後でonStart()が実行されるためです。バインディングは即時ではないので、onServiceConnected()〜 がstartService()の直後ではなく、consoleChatClientでの作業を開始するのを待ちます。これにより、適切に初期化されます。

また、getApplicationContext().unbindService()を使用してバインドを解除することもできます。アクティビティのコンテキストを使用すると機能しない可能性があります。

は、ここで私はそれを行うだろう方法は次のとおりです。あなたが `client`インスタンス変数を初期化している

public class ChatMessagesActivity extends ApplicationDrawerLoader { 

    HttpClient httpClient; 
    ConsoleChatClient consoleChatClient; 
    boolean mBound = false; 

    private ChatListener chatListener = new ChatListener(); 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     Intent intent = new Intent(this, ConsoleChatClient.class); 
     bindService(intent, mConnection, Context.BIND_IMPORTANT); 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, 
             IBinder service) { 
      ConsoleChatClient.LocalBinder binder = (ConsoleChatClient.LocalBinder) service; 
      consoleChatClient = binder.getService(); 
      mBound = true; 
      onConsoleChatClientReady() 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      mBound = false; 
     } 
    }; 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     // Unbind from the service 
     if (mBound) { 
      unbindService(mConnection); 
      mBound = false; 

      if (conversationId != 0) { 
       consoleChatClient.client.getChannel("/person/" + conversationId).unsubscribe(); 
      } 

      if (groupAccountId != 0) { 
       consoleChatClient.client.getChannel("/chat/" + conversationId).unsubscribe(); 
      } 
     } 
    } 



    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat_messages); 

     Intent intent = new Intent(this, ConsoleChatClient.class); 
     startService(intent); 


    } 

    private void onConsoleChatReady(){ 
     httpClient = consoleChatClient.httpClient; 
     if (conversationId != 0) { 
     consoleChatClient.client.getChannel("/person/" + conversationId).subscribe(chatListener); 
     } 

     if (groupAccountId != 0) { 
     consoleChatClient.client.getChannel("/chat/" + conversationId).subscribe(chatListener); 
     } 
    } 
} 
+0

どうすればonServiceConnectedを待つことができますか?ありがとう –

+0

これは魅力的に機能しました。ありがとうございます。:-)私は新しいメッセージのためにリストを直接更新することに関する1つの最終的なエラーがあります。私は質問を投稿するとここにリンクを掲載します。どうもありがとう .. :-) –

関連する問題