web-dev-qa-db-ja.com

別のクラスから現在のアクティビティまたはメインアクティビティを参照する方法

アクティビティを参照する必要があるメソッドにアクセスする必要があることがよくあります。たとえば、getWindowManagerを使用するには、アクティビティにアクセスする必要があります。しかし、これらのメソッドを使用するための私のコードは、アクティビティへの参照を持たない他のクラスにあることがよくあります。これまで、メインアクティビティへの参照を保存するか、何らかのアクティビティのコンテキストをクラスに渡しました。これを行うより良い方法はありますか?

53
AndroidDev

すでに有効なコンテキストがある場合は、これを使用します:Activity activity = (Activity) context;

19

コンテキストを渡すことは、アクティビティを参照するためのより良い方法です。

Contextを別のクラスに渡すことができます。

INアクティビティ::

AnotherClass Obj  = new AnotherClass(this);

IN Another Class

class AnotherClass{

public AnotherClass(Context Context){

    }

}
14

アクティビティに必要なメソッドを実装し、 Handler を実装できます。次に、ハンドラーインスタンスをクラスに渡すだけで、ハンドラー用のメッセージを取得してターゲットに送信できます。

5
Vladimir Ivanov

フォーラムで議論されていない非アクティビティクラスにアクティビティを取得する方法を見つけました。これは、getApplicationContext()を使用して、コンテキストをパラメーターとしてコンストラクターに渡そうとする試みが何度も失敗した後のもので、いずれもActivityを提供しませんでした。私のアダプタが受信コンテキストをアクティビティにキャストしているのを見たので、非アクティビティクラスコンストラクタにも同じキャストを行いました。

public class HandleDropdown extends Application{
...
    public Activity activity;
...
public HandleDropdown() {
    super();
}
public HandleDropdown(Activity context) {
    this.activity = context;
    this.context = context;
}
public void DropList(View v,Activity context) {
    this.activity = context;
    this.context = context; 
...
}

ContextからActivityへのキャスト変換を実行した後、Activityコンテキストが必要な場所ならどこでもthis.activityを使用できます。

4
Darrell Higgins

アクティビティの通信には多くの方法があります。

使用できます:

  • startActivityForResultメソッド

  • ブロードキャストメッセージとレシーバーのシステム(実際のアクティビティからイベントをブロードキャストし、レシーバーをターゲットアクティビティに登録できます。ターゲットアクティビティは事前に初期化され、終了していない必要があることに注意してください)

  • あなたが言うように、必要な場所にターゲットアクティビティの参照を保存してください。
2
Stefano Ortisi

アプリケーションインスタンスをシングルトンにし、コンテキストが必要なときに使用できます。

例はこの質問にあります:
シングルトンとしてのAndroidアプリケーション

このように、コンテキストが必要なときに、次のようにして取得できます
Context context = MyApplication.getInstance()

これは最もクリーンなソリューションではないかもしれませんが、これまでのところ私にとってはうまく機能しています

このためのフレームワークを構築しました。 BaseActivityから継承するActivityクラスがあり、すべてのライフサイクルメソッドをオーバーライドし、アクティビティスタックを追跡する静的(クラス)変数をいくつか持っています。現在のアクティビティを知りたい場合は、BaseActivityの静的メソッドを呼び出して、プライベートに管理されたスタックの一番上のアクティビティを返します。

ちょっとハッキーですが、動作します。私はそれをお勧めするかどうかはわかりません。

1
David Wasser

私はAndroidが初めてなので、私の提案はガチガチに見えるかもしれませんが、プライベートプロパティとしてアクティビティへの参照を作成し、それをOnCreateメソッドで割り当てるとどうなりますか? OnCreateを使用したCustomActivityは、adnroidが提供する一般的なアクティビティではなく、CustomActivityからすべてのアクティビティを派生させます。

class blah extends Activity{
  private Activity activityReference;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityReference = this;
    }

}
Intent i = new Intent(activityReference, SomeOtherActivity.class)

1
drcat

これらのメソッドを実行するクラスでインテントを処理し、次のようにバンドルで情報を送信します。

    Intent i = new Intent("Android.intent.action.MAIN");
    i.setComponent(new ComponentName("com.my.pkg","com.my.pkg.myActivity"));
    Bundle data = new Bundle();

    i.putExtras(data);

    startActivityForResult(i);

次に、OnActivityResultListenerを使用して新しいデータを取得します。

0
Jack Satriano
public static Activity getLaunchActivity()
{
    final Class<?> activityThreadClass = Class.forName("Android.app.ActivityThread");

    final Method methodApp = activityThreadClass.getMethod("currentApplication");
    App = (Application) methodApp.invoke(null, (Object[]) null);
    Intent launcherIntent = App.getPackageManager().getLaunchIntentForPackage(App.getPackageName());
    launchActivityInfo = launcherIntent.resolveActivityInfo(App.getPackageManager(), 0);
    Class<?> clazz;
    try
    {
        clazz = Class.forName(launchActivityInfo.name);
        if(clazz != null)
            return Activity.class.cast(clazz.newInstance());
    }
    catch (Exception e)
    {}

    return null;
}
0
Ali Bagheri

これを解決するには、シングルトンクラスに以下のクラスのインスタンスをメンバーとして持たせます。

public class InterActivityReferrer <T> {
    HashMap<Integer, T> map;
    ArrayList<Integer> reserve;

    public InterActivityReferrer() {
        map = new HashMap<>();
        reserve = new ArrayList<>();
    }

    public synchronized int attach(T obj) {
        int id;
        if (reserve.isEmpty()) {
            id = reserve.size();
        }
        else {
            id = reserve.remove(reserve.size() - 1);
        }

        map.put(id, obj);
        return id;
    }

    public synchronized T get(int id) {
        return map.get(id);
    }

    public synchronized T detach(int id) {
        T obj = map.remove(id);
        if (obj != null) reserve.add(id);
        return obj;
    }
}

このクラスはTオブジェクトを取得し、attach()によってオブジェクトに割り当てられた一意の整数を返すことができます。 HashMapが失敗しない限り、割り当てられた整数は互いに衝突しません。割り当てられた各整数は、対応するオブジェクトがdetach()によって切り離されると解放されます。新しいオブジェクトがアタッチされると、解放された整数が再利用されます。

そして、シングルトンクラスから:

public class SomeSingleton {
    ...
    private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
    ...
    public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}

参照する必要があるアクティビティから:

    ...
    int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
    ...

これで、このアクティビティインスタンスに対応する一意の整数が返されます。また、IntentとputExtra()を使用して、整数を別の開始アクティビティに配信できます。

    ...
    Intent i = new Intent(this, AnotherActivity.class);
    i.putExtra("thisActivityID", activityID);
    startActivityForResult(i, SOME_INTEGER);
    ...

そして別のアクティビティから:

    ...
    id refereeID = getIntent().getIntExtra("thisActivityID", -1);
    Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
    ...

最後に、アクティビティを参照できます。また、InterActivityReferrerは他のクラスに使用できます。

これがお役に立てば幸いです。

0
Chrome K