从 Fragment 类调用 Web 服务(API)的正确方法
Posted
技术标签:
【中文标题】从 Fragment 类调用 Web 服务(API)的正确方法【英文标题】:Right Approach to Call Web Service(API) from Fragment class 【发布时间】:2014-06-13 12:39:37 【问题描述】:我需要知道,在哪个fragment回调方法中,我们应该调用一个web service,返回fragment web service之后应该不会再调用。
例如。 我有一个片段类 MyFragment.java
public class MyFragment extends Fragment
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
@Override
public void onCreate(Bundle savedInstanceState)
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_layout, container,
false);
return rootView;
我需要知道我必须调用 webservice 的哪个回调方法来更新 Fragment 的 UI。 现在我正在通过onCreateView
方法调用网络服务。但我需要知道从片段调用 Web 服务的最佳方式是什么。
【问题讨论】:
【参考方案1】:如果我正确理解您的问题,您想从服务器获取一些数据,然后通知片段数据已准备好并重新绘制片段,对吗?根据文档here:
onCreate() - 系统在创建片段时调用它。在您的实现中,您应该初始化您希望在片段暂停或停止然后恢复时保留的片段的基本组件。
onCreateView() 当片段第一次绘制其用户界面时,系统会调用它。要为您的 Fragment 绘制 UI,您必须从此方法返回一个 View,它是 Fragment 布局的根。如果片段不提供 UI,则可以返回 null。
当您在应用程序的其他位置创建 Fragment 时,会调用 onCreate()
方法。当必须第一次绘制片段时,调用 onCreateView() 并且此方法返回创建的视图。在您的情况下,您可能会采用以下方式:
-
为此数据和适配器(如果使用)声明一个实例变量(容器)。
在
onCreate
中,初始化所有这些数据(空容器),初始化适配器然后执行AsyncTask
。
在onCreateView
中,准备要返回的视图- 适配器等。所以现在,一旦AsyncTask
完成,在onPostExecute
中它会调用your_adapter.notifyDataSetChanged()
。这将重绘片段,因为适配器将被告知数据已更改(从服务器获取)。
【讨论】:
【参考方案2】:取决于您何时要获取数据。 每次应用程序进入前台时你都想要它吗? 使用 onResume() 您是否仅在应用程序第一次启动时才需要它? 使用 onViewCreated(),在 onCreateView 完成后调用。
【讨论】:
【参考方案3】:onCreate() 很棘手。
把你想调用的所有东西都放在 onCreate() 方法中。 例如您的 API 调用、列表、适配器初始化。
所以理想情况下我会这样做
public void onCreate(Bundle sis)
getImagesFromServer(); // API Call
initialzeLists()
initializeAdapters()
public View onCreateView(LayoutInflater i, ViewGroup c,Bundle sis)
recyclerView = findViewById()
setUpAdapters()
return rootView;
棘手的部分
但如果你真的希望onCreate()
被调用一次,那么重用片段。 (不要每次都创建一个新实例)。
如何复用片段?
第一次添加时,使用这样的 KEY 将其添加到 backStack
currentFragment = FirstFragment.getInstance();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, currentFragment, "FIRST_KEY")
.addToBackStack("FIRST_KEY")
.commit();
当你想再次添加它时,使用这样的 KEY 获取旧实例
currentFragment = getSupportFragmentManager().findFragmentByTag("FIRST_KEY");
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, currentFragment, "FIRST_KEY")
.addToBackStack("FIRST_KEY")
.commit();
演示项目:
这是一个演示项目的链接,该项目使用 Volley 库加载图像列表。它有一个类似的实现。
Woof - Use fragments the right way
【讨论】:
通过底部导航,所有片段都在重新创建。就我而言,我只需要调用一次 API。如何通过您的方法实现这一目标? 你可以像这样添加一个布尔检查 if(!alreadyLoaded) yourAPICall();已经加载 = true以上是关于从 Fragment 类调用 Web 服务(API)的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
如何从 JavaScript 调用 REST Web 服务 API?