Как вызвать startactivityforresult из класса non-activity для получения результатов

Можно ли вызвать startActivityForResult() из класса non-activity для получения результатов?

Сценарий выглядит примерно так:

У меня есть класс NonActivity (он не выводится из Activity как его не UI). Этот класс будет иметь множество функций (шаги в основном) для запуска. Один из шагов требует, чтобы показать интерфейс (активность), а затем получить результат (пользователь что-то вводит). Затем можно было использовать эти данные в следующих следующих шагах.

Как это можно достичь без получения класса активности, поскольку у меня нет компонента пользовательского интерфейса? Кроме того, поскольку я не хочу получать из класса активности, это означает, что я не могу переопределить OnActivityResult(). Откуда берутся результаты?

Ответ 1

startActivityForResult() доступен только из реальных действий на экране, так как это метод, ну, Activity. Пожалуйста, измените свое приложение так, чтобы пользовательский интерфейс был отключен от действий.

С другой стороны, если ваш класс non Activity инициализирован и используется из экранного Activity, вы можете передать этот экземпляр Activity вашему классу в качестве параметра в конструкторе и использовать его для запуска других действий.

Будьте осторожны. Использование этого метода увеличивает риск утечки памяти, поскольку внешний класс (Utils в моем примере) может содержать ссылку на Activity даже после ее исчезновения.

Если все, что вы хотите сделать, это доступ к данным, вы можете попробовать написать его в SharedPreferences или в базе данных или в некоторых файлах, а затем использовать контекст приложения (переданный через конструктор снова), чтобы прочитать его. Это снижает риск утечки памяти. Что-то вроде:

MyApiClass myApiClass = new MyApiClass(getApplicationContext());

ПРИМЕРНЫЙ КОД

Основная деятельность:

public class Main extends FragmentActivity {

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

        Utils util = new Utils(this);
        util.startTest();

    }

    @Override
    protected void onActivityResult(int arg0, int arg1, Intent arg2) {
        Toast.makeText(this, "onActivityResult called", Toast.LENGTH_LONG).show();

        super.onActivityResult(arg0, arg1, arg2);
    }

}

Класс Utils (который запускается для результата):

public class Utils {

    Activity activity;

    public Utils(Activity ac) {
        activity = ac;
    }

    public void startTest() {
        Intent i = new Intent(activity, Test.class);
        activity.startActivityForResult(i, 1);

    }

}

Тестирование:

public class Test extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Toast.makeText(this, "Test", Toast.LENGTH_LONG).show();

        this.setResult(Activity.RESULT_OK);
        this.finish();

    }

}

Ответ 2

StartActivityForResult из класса с использованием фрагмента без видимого GUI. Вы можете найти что-то подобное в классе утилиты.

см. приведенную ниже таблицу RunGetUserAccount. Он создает свой собственный фрагмент и выполняет startActivityForResult. Затем он имеет свой собственный onActivityResult.

public class MyGooglePlay {

    private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 31502;
    private ActionBarActivity activity;
    private FragmentManager fragManager;

    public MyGooglePlay(ActionBarActivity activity) {
        this.activity = activity;
        this.fragManager = activity.getSupportFragmentManager();
    }


     /**
     * Starts an activity in Google Play Services so the user can pick an
     * account
     */
    private String mEmail = "";
    static final int REQUEST_CODE_PICK_ACCOUNT = 1000;    
    public void runGetUserAccount() {
        if (TextUtils.isEmpty(mEmail)) {
            // run this code in gui less fragment so we can pickup the 
            // on activity result from inside the mygoogleplay class.
            Fragment f = new Fragment() {
                @Override
                public void onAttach(Activity activity) {
                    super.onAttach(activity);
                    String[] accountTypes = new String[] { "com.google" };
                    Intent intent = AccountPicker.newChooseAccountIntent(null,
                            null, accountTypes, false, null, null, null, null);
                    startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
                }

                @Override
                public void onActivityResult(int requestCode, int resultCode,
                        Intent data) {
                    if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                        if (resultCode == Activity.RESULT_OK) {
                            set_Email(data
                                    .getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
                            // getUsername();
                        }
                    super.onActivityResult(requestCode, resultCode, data);
                }

                //this is to verify the fragment has been removed.
                //you can log or put a breakpoint to verify
                @Override public void onDestroy(){
                    super.onDestroy();
                }
            };
            FragmentTransaction fragmentTransaction = this.fragManager
                    .beginTransaction();
            fragmentTransaction.add(f, "getusername");
            fragmentTransaction.commit();
        }
    }

    /**
     * @param mEmail
     *            the mEmail to set
     */
    private void set_Email(String mEmail) {
        this.mEmail = mEmail;
        if (!TextUtils.isEmpty(mEmail)) {
            // TODO notify caller email is ready;
            // activity.onEmailReady(mEmail);
        }
        //we are done with the "getusername" fragment
        Fragment f = fragManager.findFragmentByTag("getusername");
        if (f!=null) {
            fragManager.beginTransaction().remove(f).commit();
        }
    }
}

Ответ 3

Если вы хотите, чтобы результат вернулся к действию в ваш обычный класс, предположил, что это класс с пользовательским адаптером внутри него.

  • вы не можете использовать startActivityForResult, потому что у вас нет активности.
  • Я сделал то, что я начал деятельность с класса с намерением. Затем я вычислил или сделал то, что должен. Из этого действия я отправляю информацию в основной класс, предположительно с помощью метода MainActivity.the_method(), и в основном действии я изменил пользовательский адаптер o сделал то, что мне нужно, используя объект адаптера и вызвав adapter.getItem(position)

Надеюсь, это может дать вам идею