我目前正在使用标签主机和片段。目前我设置片段a下载json A和片段B下载json B,问题是当我切换片段时,片段A onPostExecute
函数将落入片段B中,有没有办法解决这个问题?
感谢
标签主持人:
tabHost = (FragmentTabHost) findViewById(R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
tabHost.addTab(
tabHost.newTabSpec("Home").setIndicator("",
res.getDrawable(R.drawable.btn_about)), Home.class,
null);
tabHost.addTab(
tabHost.newTabSpec("About").setIndicator("",
res.getDrawable(R.drawable.btn_about)), About.class,
null);
异步任务
public class JSONReader {
public static final String TAG = "JSONReader";
public ArrayList<Record> records;
public Record myRecordObj;
public ArrayList<GalleryImage> images;
public String url;
public int failCount = 0; // retry twice
public Context ctx;
public String readCase;
public JSONReader(String _url, Context _ctx , String _readCase) {
url = _url;
ctx = _ctx;
readCase = _readCase;
}
public void getJSON() {
new JSONDownload().execute(url);
}
private class JSONDownload extends AsyncTask<String, Void, JSONObject> {
// TODO Auto-generated method stub
StringBuilder builder = new StringBuilder();
String temp = "";
String json = ""; // json content
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
@Override
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Log.d(TAG, "Start reading: " + url);
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return null;
// return "Server returned HTTP " + connection.getResponseCode()
// + " " + connection.getResponseMessage();
input = connection.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(input));
while ((temp = reader.readLine()) != null) {
builder.append(temp);
}
json = builder.toString();
} catch (Exception e) {
return null;
} finally {
try {
if (input != null)
input.close();
if (output != null)
output.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
try {
return new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
onJSONDownloaded(result);
}
}
public void onJSONDownloaded(JSONObject result) {
// TODO Auto-generated method stub
if (result != null) {
failCount = 0;
if (readCase.equals("leaderBoard")){
records = new ArrayList<Record>();
try {
JSONObject myRecord = result.getJSONObject("myRecord");
if (myRecord != null) {
myRecordObj = new Record(myRecord.getString("pic"),myRecord.getString("name"),myRecord.getString("score"));
}
JSONArray topRecords = result.getJSONArray("topRecord");
for (int i = 0; i < topRecords.length(); i++) {
JSONObject topRecord = topRecords.getJSONObject(i);
String topName = topRecord.getString("name");
String topPic = topRecord.getString("pic");
String topScore = topRecord.getString("score");
records.add(new Record(topPic, topName, topScore));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
((LeaderBoardDetail)ctx).setData(records,myRecordObj);
} else if (readCase.equals("galleryList")){
images = new ArrayList<GalleryImage>();
try {
JSONArray imageList = result.getJSONArray("images");
for (int i = 0; i < imageList.length(); i++) {
JSONObject image = imageList.getJSONObject(i);
images.add(new GalleryImage(image.getString("url"),image.getString("thumbUrl"),image.getString("category"),image.getString("userPic"),image.getString("name")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//exception
if (((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent).getTag().equals("Gallery")) {
PhotoGallery galleryFragment = (PhotoGallery) ((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent);
galleryFragment.setData(images);
}
}
} else {
if (failCount <= 1) { // check global_conf twice if fail
failCount++;
Log.d(TAG, "No of retry" + failCount);
new JSONDownload().execute(url); // Retry download json
} else {
failCount = 0;
}
}
}
}
答案 0 :(得分:1)
使用全局异步任务变量
LongOperation LongOperationOdeme = new LongOperation();
并设置:
LongOperationOdeme.cancel(true);
这将停止当时正在运行的任何异步任务,这是后退按钮的作用
答案 1 :(得分:1)
如果你不是在寻找一个最简单的答案,而是为了更有趣和更优雅,可以看一下this article,特别是如果你发现函数式编程很有趣。
它比它看起来容易,在本文之前我对FP几乎不熟悉,但它涵盖了与Android中的AsyncTask
和异步性相关的常见问题,因此我得到了要点并考虑使用{{1}而不是Observables
在未来的项目中自己。它是RxJava,它可以优雅地解决您的问题:“fromFragment调用转换给定的源可观察对象,只有当事件仍处于活动状态且附加到其主机活动时才会将事件发送到该片段。” / p>
该文章还有一个引用:“如果用户决定退出触发任务的Activity,并且我们正在坚持过时的参考,那会怎样。这不仅会造成大量的内存泄漏,而且也会毫无价值因为同时它已经从应用程序窗口中分离出来了。everyone is well aware of。“
的问题答案 2 :(得分:1)
我在我的应用程序中使用它,这对我有用,答案有点类似于另一个答案,但很少添加和更多细节。希望它也能帮助你。
注意:这只是一个想法,您需要尝试,它可能会因您的应用程序架构师而异。
在您的活动中,将任务对象设为全局[确保在任务完成后将任务obj设置为null]
JSDownload js = null;
public void getJSON() {
if(js != null && js.getStatus() == AsyncTask.Status.RUNNING)
{
js.cancel(true);
if(js.isCancelled())
{
js = new JSONDownload();
js.execute(url);
}
else
{
js = new JSONDownload();
js.execute(url);
}
}
在Async类的一侧.... [确保你注意null结果@ onpostExcute]
class JSONDownload extends AsyncTask<String, Void, JSONObject>
{
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
if(!this.isCancelled())
{
//make http connection ..
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
//as we are in steps in bg check iscancel .. again
//if its a loop here we call break; and return null once only..
if(this.isCancelled())
return null;
// connection status check and get buffer etc .. code here
if(this.isCancelled())
return null;
//read data
return data;
}
} catch (Exception e) {
return null;
}
}
@Override
protected void onCancelled(){
// If you write your own implementation, do not call super.onCancelled(result).
}
}