避免一次又一次地从 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
。
步骤:
在首次调用服务时将标志 didCallService = true
保存到共享首选项。将 json
响应也保存在 shared preference
中作为字符串。
当您从其他 2 个活动在 MainActivity
达到 onCreate()
时,检查用户默认设置的 didCallService
是否为真。如果是这样,请不要再次调用该服务。
在您的 AndroidManifest.xml
文件中将此 属性 添加到 MainActivity
,
<activity ..
android:launchMode= "singleTask" />
这将重新加载 MainActivity 的实例并且 onCreate()
不会被调用,而是新的意图将可用于 onNewIntent()
方法。
我正在 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
。
步骤:
在首次调用服务时将标志
didCallService = true
保存到共享首选项。将json
响应也保存在 shared preference
中作为字符串。当您从其他 2 个活动在
MainActivity
达到onCreate()
时,检查用户默认设置的didCallService
是否为真。如果是这样,请不要再次调用该服务。
在您的 AndroidManifest.xml
文件中将此 属性 添加到 MainActivity
,
<activity ..
android:launchMode= "singleTask" />
这将重新加载 MainActivity 的实例并且 onCreate()
不会被调用,而是新的意图将可用于 onNewIntent()
方法。