0

メインのアクティビティ、サービス、およびこのサービスで実行されるいくつかのスレッドを含むアプリケーションがあります。アクティビティには、1つのボタン「サービスの開始」およびその他のUIがあります。ユーザーがボタンを押すと、ボタンの名前が「サービスの停止」に変わり、プログラムはCPU使用率に関する情報を保存する新しいサービスを作成し、保存された情報を1秒ごとにTextVeiwに貼り付けます。

メインのアクティビティを停止したとしましょう。サービスは引き続き実行されますが、サービスがデータを渡すことができるアクティビティはありません。

1分後。メインアクティビティを再度起動します。まず、上記のボタンの状態(名前)'サービスの停止'を確認し、新しいアクティビティと通信し続ける古いサービスを確認します。

私のサービスは私自身のアプリケーションにとどまっているので、私は使用するつもりはありませんLocalBinderbindService(...);

解決策はありますか?

4

1 に答える 1

0

これは広範なコード例です。

開始時に、ActivityはインスタンスをApplicationにレンダリングします。私たちのアプリケーションは、メインアクティビティのインスタンス(つまり、アクティビティのインターフェイス)を保存します

見るGuiServiceBridgeItf gsb

スニペットアプリケーションクラス

public class MyApplication extends Application{ 

    private static mYApplication mSingleton;

    public GuiServiceBridgeItf gsb = null;

 @Override
 public void onCreate() {
    super.onCreate();
    mSingleton = this;
 } 

 public mYApplication getApp(){
    return mSingleton;
 }
....
}

GuiServiceBridgeItfインターフェース

public interface GuiServiceBridgeItf {
   public void onEventReceived(String str);

   /** Notify activity about service run */
   public void imHere();
....
}

これが同じインターフェースを実装するサービスですGuiServiceBridgeItfMyService2つのスレッドを実行します:

1つのスレッドがいくつかのロジックを実行します(この場合、CPUのアクティビティを毎秒通知します)

2つ目は、サービスが実行されている場合にメインアクティビティに通知します(サービスが実行されているかどうかを確認するために、このタスクをアクティビティに提供する方がよい場合があります)

public class MyService extends Service implements GuiServiceBridgeItf {

....

private RunnerThread runner = null;
private CheckAliveThread checkalive = null;

private MyApplication mMyApp = null;

public void onCreate() {
    super.onCreate();

    mMyApp  = (MyApplication)getApplicationContext();
}


public int onStartCommand(Intent intent, int flags, int startId) {

    GuiServiceBridgeItf gui2ServiceTalker = this;

    checkalive = new CheckAliveThread();
    checkalive.init(mMyApp);
    checkalive.start();


    runner = new RunnerThread(this.getApplicationContext(), gui2ServiceTalker);
    runner.start();

    ...

    return START_STICKY;
}

public void onDestroy() {   
    super.onDestroy();

    ...

    runner.doDestroy();     
    runner = null;  

    checkalive.doDestroy();
    checkalive = null;

    stopSelf();
}



private boolean isInstanceActive(){
    if(mMyApp.gsb == null){
        return false;
    }

    return true;
}


public void imHere() {}

public void onEventReceived(String str) {
    if(isInstanceActive()){
        mMyApp.gsb.onEventReceived(str);
    }
}

...

}

ここでの主なメソッドは次のとおりです。これは、または アクティビティ状態をboolean isInstanceActive()返します。つまり、Activityを停止すると、そのインスタンスをApplicationから登録解除します。メインアクティビティのメソッドがリセットされるため。truefalse
onDestroyMyApplication.gsb

一方、新しいアクティビティを再起動すると、アプリケーションに再度登録されます(以下を参照)。

public class LauncherUI extends Activity implements GuiServiceBridgeItf{

     ....
    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

            // register Activity to Application    
            GuiServiceBridgeItf gts = this;     
    mApplicationApp = (MyApplication)mContext.getApplicationContext();
    mApplicationApp .gsb = gts;

            ....
   }

   ....

    @Override
protected void onDestroy() {
   super.onDestroy();
       ....
       // Unregister Activity to prevent to Service to talk with   
       mMyApplication.gsb = null;
}

}

サービスは、スレッドを使用して、アクティビティがアプリケーションに登録されていることを検証し、CPUの変更について新生児のアクティビティに通知し続けます。今のところ、Activityはボタン名を「サービスの停止」に更新して他のことを行うことができます

于 2012-10-17T12:28:22.703 に答える