Android:绑定服务后,从Service检索的对象为null

时间:2016-03-30 12:48:47

标签: java android service

我正在开发一个Android应用程序,我在其中连接到服务并希望访问其中的对象。同一个机制适用于一个类,而另一个类则不适用于NPE。我不知道为什么和出了什么问题。你能帮忙的话,我会很高兴。

错误日志:

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);
        }
}

那么,我在错误地认为它在一个类中起作用,而在其他类中起作用。任何帮助。谢谢。

1 个答案:

答案 0 :(得分:2)

bindService()之后立即致电startService(),因为稍后会执行onStart()。绑定不是立即的,所以等待onServiceConnected() 开始使用consoleChatClient,而不是在startService()之后立即使用getApplicationContext().unbindService()。这可以保证它被正确初始化。

此外,您可能希望使用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); } } } 取消绑定,因为使用您的活动的上下文可能无效。

我将如何做到这一点:

  def full_title(page_title)
  full_title = "Your Site Title"
    if page_title.empty?
      full_title
    else
      "#{full_title} | #{page_title}"
    end    
  end