1

Web ソケットを使用するチャット アプリケーションを構築しています。Application クラスで呼び出されるサービスを作成しました。問題は、クラッシュ後にアプリを起動したときに mConnection が null になることがあるということです。アプリを終了してもバックグラウンドでサービスが実行されているためだと思いますが、再起動すると、新しいサービスを作成してバインドできません。私の質問は次のとおりです。それはコードを書く良い方法ですか? また、アプリケーションの破棄時にサービスを停止する方法はありますか?

public class MyApplication extends Application{
  private final AtomicInteger refCount = new AtomicInteger();
    public ConnectionService mConnectionService;
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            ConnectionService.MyBinder b = (ConnectionService.MyBinder) binder;
            mConnectionService = b.getService();
            Log.d("MyApplication", "MyApplication has been bounded");
        }

        public void onServiceDisconnected(ComponentName className) {
            mConnectionService = null;
            Log.d("MyApplication", "MyApplication has been unbounded");
        }
    };

    @Override
    public void onCreate() {
        Intent intent = new Intent(this, ConnectionService.class);
        getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    public ConnectionService getConnectionService() {
        refCount.incrementAndGet();
        Log.d("MyApplication", "getConnectionService, current: "+refCount);
        return mConnectionService;
    }

    public void releaseConnectionService() {

        if (refCount.get() == 0 || refCount.decrementAndGet() == 0) {
            mConnectionService.stopSelf();
            Log.d("MyApplication", "MyApplication has been stopped ");
        }
        Log.d("MyApplication", "releaseConnectionService, current: "+refCount);
    }

}

そして、別のクラスは次のようになります。

    public class LobbyActivity extends Activity{
    ListView lvContacts;
    Gson gson;
    LoginData mLoginData;
    MyReceiver receiver;
    ArrayList<User> users;
    LobbyAdapter lobbyAdapter;
    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    gson = new Gson();
    Intent intent = getIntent();
    String loginDataJson = intent.getStringExtra("LoginData");
    mLoginData = gson.fromJson(loginDataJson, LoginData.class);
    getActionBar().setTitle(mLoginData.getUsername());
    setContentView(R.layout.activity_lobby);    
    users = new ArrayList<User>();

    lvContacts = (ListView)findViewById(R.id.lvContacts);
    lobbyAdapter=new LobbyAdapter(users, this);
    lvContacts.setAdapter(lobbyAdapter);

    Commands cmd = new Commands(getApplicationContext());
    cmd.sendCommand(Commands.COMMAND_GET_MANAGER_LIST);
    cmd.sendCommand(Commands.COMMAND_GET_USER_LIST);

    receiver = new MyReceiver(new Handler()) {
        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra(ConnectionService.MESSAGE);
            String notification = intent.getStringExtra(ConnectionService.NOTIFICATION);
            if (message!=null){
                try {
                    switch (Utils.getCommand(message)) {
                    case Commands.COMMAND_GET_USER_LIST:
                        ArrayList<User> user = new ArrayList<User>();
                        user  = (gson.fromJson(message, UserList.class)).users;
                        users.addAll(user);
                        lobbyAdapter.notifyDataSetChanged();

                        break;

                    default:
                        break;
                    }



                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }
    };
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
            new IntentFilter(MainActivity.BROADCAST_ACTION));

}
    class UserList{
        String cmd;
        ArrayList<User> users; 
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ((MyApplication)getApplicationContext()).releaseConnectionService();
    }

}

サービスを Application クラスに入れる理由は、アプリケーションが実行されている限りサービスを稼働させたいからです。また、すべてのアクティビティからアクセスする必要があります。

4

1 に答える 1

1

コードを書くのは良い方法ですか?

Serviceクラスのように、またはクラスActivityからAndroid アプリのコンポーネントを開始することは、プログラミングの良い方法ではないと思いApplicationます。ActivityまたはBroadcastReceiverコンポーネントからサービスを開始する必要があります。Application onCreateアプリケーションの起動時に新しいプロセスが作成されるため、最終的に内部のコードが実行されます。これは、ランチャーからアプリを起動し、メインActivityが起動するかBroadcastReceiver、電話がかかってきた場合に発生します。現時点ではService、どちらからでも開始できます。

また、アプリケーションの破棄時にサービスを停止する方法はありますか?

Serviceアクティビティの から停止できますonDestroy()。設定を変更するたびにサービスを停止したくない場合 (画面の回転など) は、メソッドを使用して、サービスが破棄されているか、再ロードのみされているかを確認し、onDestoryその知識に基づいて停止するかどうかを決定できます。isChangingConfigurationsActivityService

于 2014-12-03T16:53:05.820 に答える