【问题标题】:Get JSON in AsyncTask Android在 AsyncTask Android 中获取 JSON
【发布时间】:2013-03-30 15:02:11
【问题描述】:

我正在尝试获取 JSON,但我必须在 AsyncTask 中进行,因为我在 logcat AndroidRuntime(18153): Caused by: android.os.NetworkOnMainThreadException 中得到了这个。

这是我的代码:

public class LatestAlbums extends Activity {

    TextView t;

    // url to make request
    private static String url = "www.example.com";

    // JSON Node names
    private static final String TAG_ALBUMS = "albums";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_SINGER = "singer";
    private static final String TAG_GENRE = "genre";
    private static final String TAG_MIX = "mix";
    private static final String TAG_THUMB = "thumb";
    private static final String TAG_SONGS = "songs";
    private static final String TAG_SONG_TITLE = "song";
    private static final String TAG_SONG_ARTIST = "artist";
    private static final String TAG_SONG_MP3 = "mp3";
    private static final String TAG_SONG_MP4 = "mp4";
    private static final String TAG_SONG_THUMB = "thumb";

    // albums JSONArray
    JSONArray albums = null;
    JSONArray sngs = null;
    JSONObject objects = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.favorites);
        t = (TextView) findViewById(R.id.json);
        loadJSON();
    }

    public void loadJSON() {
        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        try {
            // Getting Array of albums

            albums = json.getJSONArray(TAG_ALBUMS);
            sngs=json.getJSONArray(TAG_SONGS);
            // looping through All albums
            for (int i = 0; i < albums.length(); i++) {
                JSONObject c = albums.getJSONObject(i);

                // Storing each json item in variable
                String album_id = c.getString(TAG_ID);
                String album_name = c.getString(TAG_NAME);
                String album_singer = c.getString(TAG_SINGER);
                String album_genre = c.getString(TAG_GENRE);
                String album_thumb = c.getString(TAG_THUMB);

                // songs are again JSON Object
                for (int j = 0; i < sngs.length(); j++) {
                    JSONObject s = sngs.getJSONObject(j);
                    JSONObject songs = s.getJSONObject(TAG_SONGS);
                    String artist = s.getString(TAG_SONG_ARTIST);
                    String mp3 = s.getString(TAG_SONG_MP3);
                    String mp4 = s.getString(TAG_SONG_MP4);
                    String song_thumb = s.getString(TAG_SONG_THUMB);
                    String song_title = s.getString(TAG_SONG_TITLE);
                }
                Log.v("--", "Albums \n" + " " + album_id + " " + album_name
                        + " " + album_genre + " " + album_singer + " "
                        + album_thumb);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

}

谁能告诉我怎么做?

【问题讨论】:

    标签: android multithreading android-asynctask


    【解决方案1】:

    读取 JSON 并将其设置为适配器的最佳且简单的方法。

    AsyncTask 有三种方法。

    PreExecute and PostExecute 中,您可以设置任何视图属性(就像您在主 UI 线程上一样),但在 doInBackground(此处是与 UI 交互之外的操作)它读取 JSON p>

    package com.example.tabs;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.json.JSONArray;
    import org.json.JSONObject;
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import com.example.adapters.CalendarAdapter;
    import com.example.description.CalendarDescription;
    
    public class Calendar extends Activity {
    
        String url = "Enter your URL here ";
    
        GetData data;
    
        ProgressDialog progressDialog;
    
        ListView list_of_calendar;
    
        ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.calendar);
    
            list_of_calendar = (ListView) findViewById(R.id.list_of_calendar);
    
            new GetData().execute();
            //new GetData(url).execute();//you can pass it like this and see comment in doInBackground
    
            //ListView listView = getListView();
            list_of_calendar.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) 
                {
                    HashMap<String, String> map = list.get(position);               
    
                    Intent intent = new Intent(Calendar.this, CalendarDescription.class);
    
                    intent.putExtra("name", map.get("name"));
    
                    intent.putExtra("date", map.get("date"));
    
                    intent.putExtra("description", map.get("description"));
    
                    startActivity(intent);
    
    
                }
    
            });
        }
    
        private class GetData extends AsyncTask<String, Void, JSONObject> {
    
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
    
                progressDialog = ProgressDialog.show(Calendar.this,
                        "", "");
    
            }
    
            @Override
            protected JSONObject doInBackground(String... params) {
    
                String response;
    
                try {
    
                    HttpClient httpclient = new DefaultHttpClient();
    
                    HttpPost httppost = new HttpPost(url);
                    //HttpPost httppost = new HttpPost(params[0]);//you can also pass it and get the Url here. 
    
                    HttpResponse responce = httpclient.execute(httppost);
    
                    HttpEntity httpEntity = responce.getEntity();
    
                    response = EntityUtils.toString(httpEntity);
    
                    Log.d("response is", response);
    
                    return new JSONObject(response);
    
                } catch (Exception ex) {
    
                    ex.printStackTrace();
    
                }
    
                return null;
            }
    
            @Override
            protected void onPostExecute(JSONObject result) 
            {
                super.onPostExecute(result);
    
                progressDialog.dismiss();
    
                if(result != null)
                {
                    try
                    {
                        JSONObject jobj = result.getJSONObject("result");
    
                        String status = jobj.getString("status");
    
                        if(status.equals("true"))
                        {
                            JSONArray array = jobj.getJSONArray("data");
    
                            for(int x = 0; x < array.length(); x++)
                            {
                                HashMap<String, String> map = new HashMap<String, String>();
    
                                map.put("name", array.getJSONObject(x).getString("name"));
    
                                map.put("date", array.getJSONObject(x).getString("date"));
    
                                map.put("description", array.getJSONObject(x).getString("description"));
    
                                list.add(map);
                            }
    
                            CalendarAdapter adapter = new CalendarAdapter(Calendar.this, list);
    
                            list_of_calendar.setAdapter(adapter);
                        }
                    }
                    catch (Exception e) 
                    {
                        e.printStackTrace();
                    }
                }
                else
                {
                    Toast.makeText(Calendar.this, "Network Problem", Toast.LENGTH_LONG).show();
                }
            }
    
        }
    }
    

    编辑

    代码用于网址

    http://www.socialgeolocate.com/DayCare/webservices/Get_calender.php?

    【讨论】:

    • 哪个是该解析的 json 结构的示例?我不理解“结果”、“状态”和“数据”字符串。谢谢。
    • 卡洛看到我更新的答案。我附上了我从中获取数据的链接。
    • 谢谢 nepster,我对如何获得一个干净的 json 数组有疑问(我的意思是,之前没有字典或 JSONObjects)但我知道我应该在整个 asyncTask 中使用 JSONArray 而不是 JSONObject,这就是为什么我想看到那个读取的 JSON,再次感谢..
    • 您的示例 URL 仅返回 text/html 为什么不使用 application/json MIME 类型返回内容?
    • 现在我无法访问它。 jap 1968 但您可以通过添加 google chrome jsonview 插件来查看 json。
    【解决方案2】:

    在后台加载您的 JSON 对象(进行网络操作)并在 UI 线程中处理结果,即:

    URL requestUrl = "...";
    
    new AsyncTask<URL, Void, JSONObject>() {
    
        @Override
        protected Boolean doInBackground(URL... urls) {
            loadJSON(url);
        }
    
        @Override
        protected void onPostExecute(JSONObject jsonData) {
            try {
                // Getting Array of albums
    
                albums = json.getJSONArray(TAG_ALBUMS);
                sngs=json.getJSONArray(TAG_SONGS);
                // looping through All albums
    
                etc.
        }
    }.execute(requestUrl);
    
    
    public void loadJSON(URL url) {
        // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();
    
        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(url);
    
        return json;
    }
    

    查看this了解更多信息。

    干杯!

    【讨论】:

    • 当我把它放在我的代码中时,我遇到了很多错误。我必须把它放在一个新的类中吗
    • 我只是想给你一个粗略的想法。当然,还有一些事情要做。但是这个想法应该很清楚,不是吗?附:如果您卡在某个地方,请粘贴更新后的代码并添加不起作用的部分
    • @BozidarPrcovski 你在developers.android.com 上读过ASyncTask 吗?如果是这样,那么在实施时应该没有任何问题。
    【解决方案3】:

    This is how a asynctask works

    中进行解析
    doInBackground()
    

    然后用检索到的数据做事

    onPostExecute()
    

    【讨论】:

      猜你喜欢
      • 2015-03-28
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 2016-10-26
      相关资源
      最近更新 更多