2013-01-10 43 views
12

是否可以從非活動類調用startActivityForResult()以獲取結果?如何從非活動類調用startactivityforresult以獲得結果

的情況是這樣的:

我有一個類NonActivity(它不會從活動作爲它不是一個UI獲得)。 這個類將有一堆函數(基本步驟)運行。 其中一個步驟需要顯示UI(活動),然後得到結果(用戶輸入的東西)。 然後就可以在接下來的步驟中使用這些數據。

如何在不從活動類派生的情況下實現這一點,因爲我沒有UI組件? 另外,因爲我不想從活動課派生,這意味着我無法覆蓋OnActivityResult()。結果究竟來自哪裏?

回答

15

startActivityForResult()只能從真實的屏幕上活動中獲得,因爲它是活動中的一種方法。請重新設計您的應用程序,以便從活動中驅動用戶界面。另一方面,如果您的非Activity類是通過屏幕上的Activity初始化並使用的,則可以將該Activity的實例作爲構造函數中的參數傳遞給您的類,並使用它來啓動其他Activities。

但要小心。使用這種方法會增加內存泄漏的風險,因爲外部類(在我的示例中爲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(); 

    } 

} 
+0

startActivityForResult方法不能從非活動類工作監守我們只能在活動 –

+0

@ρяσѕρєяK我只是想它覆蓋onActivityresult,它工作正常。讓我發佈一些示例代碼。 –

+0

感謝您的回覆。使用非活動類的基本原因是我想將整個過程封裝到一個類(API)中,那麼任何想使用此類的人都可以調用它的API。該API執行一系列步驟,其中一些涉及以活動形式從用戶處獲取數據。即使我們忘記了startActivityForResult,我所需要的是來自非活動類中的活動的數據是這種情況在android中不是有效的嗎? – user1950373

7

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(); 
     } 
    } 
} 
+0

但是,您正在構造函數中傳遞一個活動,該操作只想使用活動來獲取片段管理器,而不是使用活動 – Yashasvi

+0

。它沒有什麼特別的魔法。我實際上是從一個片段調用此代碼並在調用之前將其投射到活動。拋棄一個以片段爲輸入的類,我無法從一個活動調用它,因此它不會被重用。當你從一個片段調用getActivityForResult時,它會起作用,否則結果會返回到主要活動。也許它的固定,我們現在在什麼版本N.也許使用這種方法,它可以幫助你。祝你好運 – danny117

0

如果你想從活動回到你的普通類的結果,假設它是一個具有自定義適配器的類。

  1. 你不能使用startActivityForResult,因爲你是在一個活動
  2. 我所做的是我發起活動從類的意圖。然後我計算或做了我必須做的。在這個活動中,我將信息發送到MainActivity.the_method()方法的主類中,並在主要活動中更改了自定義適配器o做了必須使用適配器對象並調用adapter.getItem(position)

希望這可以給你出個主意

相關問題