繁体   English   中英

从异步任务上的URL提取数据时,主线程冻结

[英]Main thread freezes when fetching data from URL on Async Task

我正在使用AsycTask从URL提取JSON,对其进行解析并将数据显示到listView上。 我还单击刷新按钮,再次从URL获取JSON以进行一些更新。 当我单击刷新按钮时,将发生以下情况: 1)adapter.clear():清除listView的适配器以填充新数据。 2)从url获取JSON,解析并将新获取的数据显示在listView上。 3)同时,在获取数据时,我显示一个进度对话框。

但是,当我单击刷新按钮时,在执行AsynTask时主UI线程将冻结。 我的意思是刷新按钮看起来一直按下,直到AsynTask完成工作,如下所示。 在此处输入图片说明

这是我的代码:

public class AndroidJSONParsingActivity extends SherlockActivity {

    // JSON Node names
    ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
    private static final String TAG_PLACES = "places";
    private static final String TAG_PLACE_NAME = "name";
    private static final String TAG_PLACE_CATEGORY = "category";
    private static final String TAG_PLACE_DISTANCE = "distance";
    private static final String TAG_TRAVEL_TIME = "travel_time";
    ListAdapter adapter;
    public static Context con;
    JSONArray places = null;
    ListView list;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        con = this;
        list = (ListView) findViewById(R.id.listView1);
        parseJSON();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.activity_main, menu);

        MenuItem menu_item1 = menu.findItem(R.id.menu_item1);

        menu_item1.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(getApplicationContext(), "refresh",
                        Toast.LENGTH_LONG).show();
                placeList.clear();
                parseJSON();
                return false;
            }
        });

        return true;

    }

    public void parseJSON() {
        try {
            placeList = new JSONParsingTask().execute().get();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        adapter = new SimpleAdapter(this, placeList, R.layout.list_item,
                new String[] { TAG_PLACE_NAME, TAG_PLACE_CATEGORY,
                        TAG_PLACE_DISTANCE, TAG_TRAVEL_TIME }, new int[] {
                        R.id.name, R.id.category, R.id.distance,
                        R.id.travel_time });

        list.setAdapter(adapter);

        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                String name = ((TextView) view.findViewById(R.id.name))
                        .getText().toString();
                String category = ((TextView) view.findViewById(R.id.category))
                        .getText().toString();
                String distance = ((TextView) view.findViewById(R.id.distance))
                        .getText().toString();
                String travel_time = ((TextView) view
                        .findViewById(R.id.travel_time)).getText().toString();

                Intent in = new Intent(getApplicationContext(),
                        SingleMenuItemActivity.class);
                in.putExtra(TAG_PLACE_NAME, name);
                in.putExtra(TAG_PLACE_CATEGORY, category);
                in.putExtra(TAG_PLACE_DISTANCE, distance);
                in.putExtra(TAG_TRAVEL_TIME, travel_time);
                startActivity(in);

            }
        });

    }

}

class JSONParsingTask extends
        AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
    public Boolean flag = false;
    private static String url = "http://some - url";

    // JSON Node names

    private static final String TAG_PLACES = "places";
    private static final String TAG_PLACE_NAME = "name";
    private static final String TAG_PLACE_CATEGORY = "category";
    private static final String TAG_PLACE_DISTANCE = "distance";
    private static final String TAG_TRAVEL_TIME = "travel_time";
    ListAdapter adapter;
    JSONParser jParser;
    ListView list;
    static ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
    JSONArray places = null;

    ProgressDialog JSONParsingDialog = new ProgressDialog(
            AndroidJSONParsingActivity.con);

    @Override
    protected void onPreExecute() {
        JSONParsingDialog.setMessage("Preparing data...");
        JSONParsingDialog.setCanceledOnTouchOutside(false);
        JSONParsingDialog.setCancelable(false);
        JSONParsingDialog.show();
    }

    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
        JSONParser jParser = new JSONParser();

        final JSONObject json = jParser.getJSONFromUrl(url);

        try {
            places = json.getJSONArray(TAG_PLACES);

            for (int i = 0; i < places.length(); i++) {
                JSONObject c = places.getJSONObject(i);

                String name = c.getString(TAG_PLACE_NAME);
                String category = c.getString(TAG_PLACE_CATEGORY);
                String distance = c.getString(TAG_PLACE_DISTANCE);
                String travel_time = c.getString(TAG_TRAVEL_TIME);

                HashMap<String, String> map = new HashMap<String, String>();

                map.put(TAG_PLACE_NAME, name);
                map.put(TAG_PLACE_CATEGORY, category);
                map.put(TAG_PLACE_DISTANCE, distance);
                map.put(TAG_TRAVEL_TIME, travel_time);

                placeList.add(map);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return placeList;
    }

    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        JSONParsingDialog.dismiss();
    }

}

我需要的是,当我单击刷新按钮时,它应该是平滑的,并且在AsynTask完成之前不应该冻结。 知道我该怎么做吗?

采用

new JSONParsingTask().execute(); 

.get()阻止调用者线程。

更多信息: 寻找在Android中将get()与AsyncTask一起使用的好例子

像这样尝试:

public class AndroidJSONParsingActivity extends SherlockActivity {

// JSON Node names
ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
public static Context con;
JSONArray places = null;
ListView list;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    con = this;
    list = (ListView) findViewById(R.id.listView1);
    fetchJSON();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.activity_main, menu);

    MenuItem menu_item1 = menu.findItem(R.id.menu_item1);

    menu_item1.setOnMenuItemClickListener(new OnMenuItemClickListener() {

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            Toast.makeText(getApplicationContext(), "refresh",
                    Toast.LENGTH_LONG).show();
            placeList.clear();
            parseJSON();
            return false;
        }
    });

    return true;

}

public void fecthJson(){
    new JSONParsingTask().execute();
}

public void parseJSON(ArrayList<Hashmap<String, String>> dataList) {

    adapter = new SimpleAdapter(this, dataList, R.layout.list_item,
            new String[] { TAG_PLACE_NAME, TAG_PLACE_CATEGORY,
                    TAG_PLACE_DISTANCE, TAG_TRAVEL_TIME }, new int[] {
                    R.id.name, R.id.category, R.id.distance,
                    R.id.travel_time });

    list.setAdapter(adapter);

    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            String name = ((TextView) view.findViewById(R.id.name))
                    .getText().toString();
            String category = ((TextView) view.findViewById(R.id.category))
                    .getText().toString();
            String distance = ((TextView) view.findViewById(R.id.distance))
                    .getText().toString();
            String travel_time = ((TextView) view
                    .findViewById(R.id.travel_time)).getText().toString();

            Intent in = new Intent(getApplicationContext(),
                    SingleMenuItemActivity.class);
            in.putExtra(TAG_PLACE_NAME, name);
            in.putExtra(TAG_PLACE_CATEGORY, category);
            in.putExtra(TAG_PLACE_DISTANCE, distance);
            in.putExtra(TAG_TRAVEL_TIME, travel_time);
            startActivity(in);

        }
    });

}

}

class JSONParsingTask extends
    AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
public Boolean flag = false;
private static String url = "http://some - url";

// JSON Node names

private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
JSONParser jParser;
ListView list;
static ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
JSONArray places = null;

ProgressDialog JSONParsingDialog = new ProgressDialog(
        AndroidJSONParsingActivity.con);

@Override
protected void onPreExecute() {
    JSONParsingDialog.setMessage("Preparing data...");
    JSONParsingDialog.setCanceledOnTouchOutside(false);
    JSONParsingDialog.setCancelable(false);
    JSONParsingDialog.show();
}

@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
    JSONParser jParser = new JSONParser();

    final JSONObject json = jParser.getJSONFromUrl(url);

    try {
        places = json.getJSONArray(TAG_PLACES);

        for (int i = 0; i < places.length(); i++) {
            JSONObject c = places.getJSONObject(i);

            String name = c.getString(TAG_PLACE_NAME);
            String category = c.getString(TAG_PLACE_CATEGORY);
            String distance = c.getString(TAG_PLACE_DISTANCE);
            String travel_time = c.getString(TAG_TRAVEL_TIME);

            HashMap<String, String> map = new HashMap<String, String>();

            map.put(TAG_PLACE_NAME, name);
            map.put(TAG_PLACE_CATEGORY, category);
            map.put(TAG_PLACE_DISTANCE, distance);
            map.put(TAG_TRAVEL_TIME, travel_time);

            placeList.add(map);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return placeList;
}

@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
    // TODO Auto-generated method stub
    super.onPostExecute(result);
    JSONParsingDialog.dismiss();
    placeList = result;
    parseJson(result);
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM