Android 将方法从一个活动调用到另一个活动的片段。正确的方法是什么?

Android 将方法从一个活动调用到另一个活动的片段。正确的方法是什么?,android,android-activity,android-fragments,callback,Android,Android Activity,Android Fragments,Callback,这可能已经回答了,但我仍然对这样的函数感到不安。假设我有活动A和活动B。B持有一个viewpager,其中有几个片段。我想从活动a调用活动B持有的片段中的函数 我多次使用回调在活动和片段之间进行通信,但每次都只是片段及其持有者活动。我不想创建一个静态方法(回调侦听器无论如何都不能是静态的),因此它会让我头疼。在片段中创建一个静态方法并从另一个调用它的简单静态解决方案实际上非常有效,但我不确定这是否是一个好主意,因为我需要更改几个静态的东西 因此,在活动B及其片段之间进行通信是可以的,但我不能在活

这可能已经回答了,但我仍然对这样的函数感到不安。假设我有活动A活动B。B持有一个
viewpager
,其中有几个片段。我想从活动a调用活动B持有的片段中的函数

我多次使用回调在活动和片段之间进行通信,但每次都只是片段及其持有者活动。我不想创建一个静态方法(回调侦听器无论如何都不能是静态的),因此它会让我头疼。在片段中创建一个静态方法并从另一个调用它的简单静态解决方案实际上非常有效,但我不确定这是否是一个好主意,因为我需要更改几个静态的东西

因此,在活动B及其片段之间进行通信是可以的,但我不能在活动A中调用此方法

活动B:

public class ActivityB extends FragmentActivity implements Fragment1.OnWhateverListener                           
                          {  
...

@Override
    public void onWhateverSelected(int position) {  
         //stuff, here I can call any function in Fragment 1
    }

}
ActivityB ab = new ActivityB ();
ab.onWhateverSelected(number);
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    ...
    processIntent(getIntent()); //last line of onCreate, always gets called here
    }


     @Override
     public void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            processIntent(intent); // this never gets called here only in OnCreate
     }

     private void processIntent(Intent intent) {
                Bundle args = intent.getBundleExtra("args");
                if (args != null) { // check if ActivityB is started to pass data to fragments
                    String id = args.getString("ID");


            Log.i("ID_FROM", "id: " + id);   //works well
                        if (id != null) {
                          List<Fragment> fragments = new ArrayList<Fragment>();
                          fragments = getSupportFragmentManager().getFragments();
                       //NULLPOINTER for the following line 
                          FragmentMainDiscover fr = (FragmentMainDiscover) fragments.get(0);  
                          fr.RefreshHoverView(id);
                        }
                    }
                }
下面的代码片段是一个错误的解决方案(甚至不起作用),但它使我能够更好地理解我想要做的事情

活动A:

public class ActivityB extends FragmentActivity implements Fragment1.OnWhateverListener                           
                          {  
...

@Override
    public void onWhateverSelected(int position) {  
         //stuff, here I can call any function in Fragment 1
    }

}
ActivityB ab = new ActivityB ();
ab.onWhateverSelected(number);
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    ...
    processIntent(getIntent()); //last line of onCreate, always gets called here
    }


     @Override
     public void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            processIntent(intent); // this never gets called here only in OnCreate
     }

     private void processIntent(Intent intent) {
                Bundle args = intent.getBundleExtra("args");
                if (args != null) { // check if ActivityB is started to pass data to fragments
                    String id = args.getString("ID");


            Log.i("ID_FROM", "id: " + id);   //works well
                        if (id != null) {
                          List<Fragment> fragments = new ArrayList<Fragment>();
                          fragments = getSupportFragmentManager().getFragments();
                       //NULLPOINTER for the following line 
                          FragmentMainDiscover fr = (FragmentMainDiscover) fragments.get(0);  
                          fr.RefreshHoverView(id);
                        }
                    }
                }
那我该怎么做呢? 谢谢大家!

编辑

活动A:我调用的方法

  Bundle args = new Bundle();
   args.putString("ID", id); // the data to send
   Intent frag_args = new Intent(Intent.ACTION_VIEW);
   frag_args.setClass(this, MainActivity.class);
   frag_args.putExtra("args", args);
   startActivity(frag_args);
活动B:

public class ActivityB extends FragmentActivity implements Fragment1.OnWhateverListener                           
                          {  
...

@Override
    public void onWhateverSelected(int position) {  
         //stuff, here I can call any function in Fragment 1
    }

}
ActivityB ab = new ActivityB ();
ab.onWhateverSelected(number);
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    ...
    processIntent(getIntent()); //last line of onCreate, always gets called here
    }


     @Override
     public void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            processIntent(intent); // this never gets called here only in OnCreate
     }

     private void processIntent(Intent intent) {
                Bundle args = intent.getBundleExtra("args");
                if (args != null) { // check if ActivityB is started to pass data to fragments
                    String id = args.getString("ID");


            Log.i("ID_FROM", "id: " + id);   //works well
                        if (id != null) {
                          List<Fragment> fragments = new ArrayList<Fragment>();
                          fragments = getSupportFragmentManager().getFragments();
                       //NULLPOINTER for the following line 
                          FragmentMainDiscover fr = (FragmentMainDiscover) fragments.get(0);  
                          fr.RefreshHoverView(id);
                        }
                    }
                }
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
...
...
processIntent(getIntent());//onCreate的最后一行总是在这里被调用
}
@凌驾
公共帐篷(意向){
super.onNewIntent(意向);
processIntent(intent);//这里永远不会只在OnCreate中调用它
}
私有void processIntent(Intent-Intent){
Bundle args=intent.getBundleExtra(“args”);
如果(args!=null){//请检查ActivityB是否已开始向片段传递数据
字符串id=args.getString(“id”);
Log.i(“ID_FROM”,“ID:+ID);//工作正常
如果(id!=null){
List fragments=new ArrayList();
片段=getSupportFragmentManager().getFragments();
//下一行的空指针
FragmentMainDiscover fr=(FragmentMainDiscover)fragments.get(0);
前视图(id);
}
}
}

远离静态是正确的。对于可能在屏幕上或不在屏幕上的可视对象来说,这太危险了

我建议进行活动B,因为它是目标片段的父级。创建一个启动活动B的意图,并包含一个额外的意图,告诉活动B应该对目标片段做什么。然后活动B可以确保片段正在显示,并将信息传递给它

将信息传递给片段的另一个想法是使用setArguments,而不是直接调用。这是一种很好的方法,因为如果从内存中删除活动及其片段,Android将自动恢复参数

这有意义吗?你要密码吗

编辑

要使用参数,您仍然需要让活动A通过活动B。这是因为活动A不知道活动B及其所有片段是否正在运行,除非它向其发送一个意图。但是,您可以通过将片段放在intent中来包含针对片段的数据。像这样:

public class ActivityA extends Activity {
    public static final String KEY_FRAG = "frag"; // tells activity which fragment gets the args
    public static final String KEY_ARGS = "args";
    public static final String KEY_MY_PROPERTY = "myProperty";

    public void foo() {
        Bundle args = new Bundle();
        args.putString(KEY_FRAG, "frag1Tag"); // which fragment gets the data
        args.putCharSequence(KEY_MY_PROPERTY, "someValue"); // the data to send

        // Send data via an Intent, to make sure ActivityB is running
        Intent frag_args = new Intent(Intent.ACTION_VIEW);
        frag_args.setClass(this, ActivityB.class);
        frag_args.putExtra(KEY_ARGS, args);
        startActivity(frag_args);
    }
}

public class ActivityB extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //TODO configure activity including fragments
        processIntent(getIntent()); // this call is in case ActivityB was not yet running
    }

    @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        processIntent(intent); // this call is in case ActivityB was already running 
    }

    private void processIntent(Intent intent) {
        Bundle args = intent.getBundleExtra(ActivityA.KEY_ARGS);
        if (args != null) { // check if ActivityB is started to pass data to fragments
            String fragTag = args.getString(ActivityA.KEY_FRAG);
            if (fragTag != null) {
                Fragment frag = getSupportFragmentManager().findFragmentByTag(fragTag);
                frag.setArguments(args);
                //TODO either show the fragment, or call a method on it to let it know it has new arguments
            }
        }
    }
}

public class Fragment1 extends Fragment {
    public static final String TAG = "frag1Tag";
    @Override
    public void onResume() {
        super.onResume();
        Bundle args = getArguments();
        String value = args.getString(ActivityA.KEY_MY_PROPERTY);
        ...
    }
}

我用插入的代码编辑了我的问题。问题是我得到了一个指示行的空指针。当我在另一个上下文中使用此代码时,它会正确地找到片段。我也不知道NewIntent重写的方法永远不会被调用,只有OnCreate运行。这可能会导致空指针。无论如何,我不想启动其他活动,只需调用该方法。我可以把frag_args.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)放在上面;但这清除了当前的活动。