3

こんにちは: 同じパッケージ内のサービスにバインドするアクティビティを取得できないようです。

アクティビティは次のようになります。

public class myApp extends TabActivity {
    static private String TAG = "myApp";
    private myService mService = null;
    private ServiceConnection mServiceConn = new ServiceConnection(){
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.v(TAG, "Service: " + name + " connected");
            mService = ((myService.myBinder)service).getService();
        }

        public void onServiceDisconnected(ComponentName name) {
            Log.v(TAG, "Service: " + name + " disconnected");
        }
    };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        doBind();
        Log.i(TAG, "Started (UI Thread)");

        // set content
        setContentView(R.layout.main);

        Resources res = getResources(); // Resource object to get Drawables
        TabHost tabHost = getTabHost();  // The activity TabHost

        ... add some tabs here....

        tabHost.setCurrentTab(0);
    }

    private void doBind(){      
        Intent i = new Intent(this,myService.class);
        if( bindService(i, mServiceConn, 0 )){
            Log.i(TAG, "Service bound");
        } else {
            Log.e(TAG, "Service not bound");
        }
    }

}

次に、サービス:

public class myService extends Service {
    private String TAG = "myService";

    private boolean mRunning = false;

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) {
        Log.i(TAG,"Service start");

        mRunning = true;

        Log.d(TAG,"Finished onStartCommand");
        return START_STICKY;
    }

    /*
     * Called on service stop
     */
    @Override
    public void onDestroy(){
        Log.i(TAG,"onDestroy");
        mRunning = false;
        super.onDestroy();
    }

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


    boolean isRunning() {
        return mRunning;
    }

    /*
     * class for binding
     */
    private final IBinder mBinder = new myBinder();
    public class myBinder extends Binder {
        myService getService() {
            return myService.this;
        }
    }
}

bindService は true を返しますが、onServiceConnection は呼び出されません (mService は常に null なので、 mService.isRunning() のようなことはできません)。

サービスのマニフェスト エントリは次のとおりです。

<service android:name=".myService"></service>

Android 開発者サイトからコードを直接コピーしていましたが、何か見落としていたに違いありません。

4

2 に答える 2

25

タブアクティビティ (タブホストで実行) のサブアクティビティとして開始されたアクティビティは、同じパッケージであってもサービスにバインドできないという既知の問題があります。「ハック」回避策があります。あなたが呼び出す場合:

 getApplicationContext().bindService(Intent, connection, flags);

だけではなく:

 bindService(Intent, connection, flags);

すべてが機能します。この同じ問題があり、このバグレポートで詳細を見つけました: http://code.google.com/p/android/issues/detail?id=2483

于 2011-03-22T23:53:36.130 に答える
3

サービスが開始されることはありません。でサービスを開始 startService(bindIntent)

次の類似のコードを参照してください。

Intent bindIntent = new Intent(this,ServiceTask.class);
if (ServiceTools.isServiceRunning() == false){
    Log.d(Global.TAG,"-->service will be started.");
    startService(bindIntent);
}else{
    Log.d(Global.TAG,"-->service already is running");
}
boolean bound = bindService(bindIntent,mConnection,0);

0 の代わりに BIND_AUTO_CREATE でバインドすると、サービスを自動的に開始することもできます。

サービスを 1 回だけ開始する場合も、ServiceTools クラスを次に示します。そうしないと、サービスの実行中のインスタンスが複数取得される可能性があり、onServiceConnected で呼び出されるメソッドは、onCreate() / doBind() が実行されるたびにわだち掘れになります。

public class ServiceTools {
    public static boolean isServiceRunning(){
        final ActivityManager activityManager = (ActivityManager)Global.gContext.getSystemService(Global.gContext.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        boolean isServiceFound = false;

        for (int i = 0; i < services.size(); i++) {
            //Log.d(Global.TAG, "Service" + i + " :" + services.get(i).service);
            //Log.d(Global.TAG, "Service" + i + " package name : " + services.get(i).service.getPackageName());
            //Log.d(Global.TAG, "Service" + i + " class name : " + services.get(i).service.getClassName());

            if ("com.atClass.lmt".equals(services.get(i).service.getPackageName())){
                if ("com.atClass.lmt.ServiceTask".equals(services.get(i).service.getClassName())){
                    isServiceFound = true;
                }
            }
        }
        return isServiceFound;
     }
}
于 2011-02-26T18:54:48.650 に答える