サービスからアクティビティの参照を取得する

android android-activity android-intent android-service
サービスからアクティビティの参照を取得する

サービスからメインアクティビティへの参照を取得する必要があります。

これは私のデザインです:

  • MainActivity.java *

public class MainActivity extendsActivity{
private Intent myIntent;
onCreate(){
 myIntent=new Intent(MainActivity.this, MyService.class);

 btnStart.setOnClickListener(new OnClickListener(){
  public void onClick(View V){
   startService(myIntent);
   });
}}
  • MyService.java *

class MyService extends Service{

 public IBinder onBind(Intent intent) {
  return null;
 }

 onCreate(){
 //Here I need to have a MainActivity reference
 //to pass it to another object
 }
}

どのようにできるのか?

  • [編集] *

答えてくれてありがとう! このアプリはWebサーバーであり、現時点ではスレッドでのみ機能します。代わりにサービスを使用して、バックグラウンドでも機能するようにします。 問題は、アセットからページを取得するクラスを持っていることです。この操作を行うには、このメソッドを使用する必要があります。

InputStream iS =myActivity.getAssets().open("www/"+filename);

現時点では、プロジェクトにはアクティビティが1つしかなく、サービスはありません。そのため、メインアクティビティの参照をそれ自体から直接渡すことができます。

WebServer ws= new DroidWebServer(8080,this);

だから、このアプリをサービスで動作させるために、私のデザインで何を変更する必要がありますか?

  7  3


ベストアンサー

これが必要な理由を説明しませんでした。 しかし、これは間違いなく「悪い」デザインです。 アクティビティへの参照を保存することは、アクティビティで最初に行うべきではないことです。 できますが、アクティビティのライフサイクルを追跡し、 `onDestroy()`が呼び出された後に参照を解放する必要があります。 これを行わない場合、メモリリークが発生します(たとえば、構成が変更された場合)。 そして、まあ、 `onDestroy()`が呼び出された後、アクティビティは死んでいるとみなされ、とにかくほとんど役に立たないでしょう。

そのため、参照をサービスに保存しないでください。 代わりに達成する必要があるものを説明してください。 もっと良い選択肢があると確信しています。

” ” ‘

更新

わかりましたので、実際にアクティビティを参照する必要はありません。 代わりに、Contextへの参照が必要です(この場合、Activityまたは他のコンポーネントへの参照を保持しないためにApplicationContextにする必要があります)。

WebServiceリクエストを処理する別のクラスがあると仮定します。

class WebService
{
     private final Context mContext;
     public WebService(Context ctx)
     {
        //The only context that is safe to keep without tracking its lifetime
        //is application context. Activity context and Service context can expire
        //and we do not want to keep reference to them and prevent
        //GC from recycling the memory.
        mContext = ctx.getApplicationContext();
     }

     public void someFunc(String filename) throws IOException
     {
         InputStream iS = mContext.getAssets().open("www/"+filename);
     }
}

これで、 Service(このようなバックグラウンドタスクに推奨)から、または` Activity`(Webサービス呼び出しや長いバックグラウンドタスクが関係する場合に正しく取得するのがはるかに難しい)からWebServiceインスタンスを作成して使用できます。

「サービス」の例:

class MyService extends Service
{
    WebService mWs;
    @Override
    public void onCreate()
    {
        super.onCreate();
        mWs = new WebService(this);

       //you now can call mWs.someFunc() in separate thread to load data from assets.
    }

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

8


サービスとアクティビティの間で通信するには、AIDLを使用する必要があります。 このリンクの詳細:

編集:(Renan Malke Stiglianiに感謝)http://developer.android.com/guide/components/aidl.html

2


AIDLは、アクティビティとサービスが個別のapkに含まれていない限り過剰です。

ローカルサービスにバインダーを使用するだけです。 (ここに完全な例:http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

2


inazarukのコメントに同意します。 しかし、アクティビティとサービスの間の通信に関しては、いくつかの選択肢があります-AIDL(前述)、Messenger、BroadcastReiceverなど。 MessengerメソッドはAIDLに似ていますが、インターフェイスを定義する必要はありません。 ここから始めることができます。

0


タイトルとURLをコピーしました