Как вызвать 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)
Надеюсь, это может дать вам идею