避免一次又一次地从 JSON 中获取数据

Avoid Fetching Data from JSON again and again

我正在 MainActivity 中解析来自服务器的 JSON 数据,但每当我切换到另一个 Activity 然后再次调用 MainActivity...问题,它再次命中 JSON url,再次从 JSON.

获取数据

为什么?而我已经从 JSON

下载了数据
public class MainActivity extends Activity {

    ArrayList<Actors> actorsList;

    ActorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        actorsList = new ArrayList<Actors>();
        new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors");

        ListView listview = (ListView)findViewById(R.id.list);
        adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);

        listview.setAdapter(adapter);

        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long id) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();              
            }
        });
    }


    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Loading, please wait");
            dialog.setTitle("Connecting server");
            dialog.show();
            dialog.setCancelable(false);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {

                //------------------>>
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);

                // StatusLine stat = response.getStatusLine();
                int status = response.getStatusLine().getStatusCode();

                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);


                    JSONObject jsono = new JSONObject(data);
                    JSONArray jarray = jsono.getJSONArray("actors");

                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        Actors actor = new Actors();

                        actor.setName(object.getString("name"));
                        actor.setDescription(object.getString("description"));
                        actor.setDob(object.getString("dob"));
                        actor.setCountry(object.getString("country"));
                        actor.setHeight(object.getString("height"));
                        actor.setSpouse(object.getString("spouse"));
                        actor.setChildren(object.getString("children"));
                        actor.setImage(object.getString("image"));

                        actorsList.add(actor);
                    }
                    return true;
                }

                //------------------>>

            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            adapter.notifyDataSetChanged();
            if(result == false)
                Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();

        }
    }   
}

尝试使用静态变量

 static boolean flag=false;
 static ArrayList<Actors> actorsList;

然后在调用 AsyncTask 之前检查标志是真还是假

if(!flag){
 actorsList = new ArrayList<Actors>(); //use this inside if statement
 new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors");
flag=true;
}

所以只有当标志为 false 时才会执行异步任务... 希望这有帮助。

获取一个 boolean 变量并将其初始化为 true 并将其状态保存到 sharedpreference。现在,当 MainActivity 启动时,使用 sharedpreference 检查此 boolean 是否为真。如果为真,则获取 JSON 并将 boolean 变为假,并将 boolean 的状态保存为 sharedpreference。现在,每当 MainActivity 被调用时,因为 boolean 为 false,JSON 将不会被获取。

你可以使用 "savedInstanceState" varibale 来达到这个目的,请检查下面的代码

if(savedInstanceState==null)
{
     new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors");
}

第一次启动时 activity 它的 savedInstanceState 为空,下次 t 有值时,请在您的代码中添加上述条件。

根据您的评论“I am calling MainActivity from SecondActivity using onBackPressed() and also calling MainActivity from ThirdActivity using Intent.

在 SecondActivity onBackPressed() 时:简单地调用 finish() 不会重新加载 MainActivity,因此它不会重新加载并再次调用 Web 服务。

另一种选择是有一个标志,保存在 shared preferences

步骤:

  1. 在首次调用服务时将标志 didCallService = true 保存到共享首选项。将 json 响应也保存在 shared preference 中作为字符串。

  2. 当您从其他 2 个活动在 MainActivity 达到 onCreate() 时,检查用户默认设置的 didCallService 是否为真。如果是这样,请不要再次调用该服务。

使用singleTask

在您的 AndroidManifest.xml 文件中将此 属性 添加到 MainActivity,

<activity ..
      android:launchMode= "singleTask" />

这将重新加载 MainActivity 的实例并且 onCreate() 不会被调用,而是新的意图将可用于 onNewIntent() 方法。