【问题标题】:Android - getting very big JSON array from web - cause crushAndroid - 从网络获取非常大的 JSON 数组 - 导致迷恋
【发布时间】:2014-04-01 15:55:14
【问题描述】:

我正在开发 Android 应用程序,它从网络服务器(通过 AsyncTask)获取非常大的 JSON 数组,有时它会崩溃,有时它不会 - 我认为这是因为我正在接收一个巨大的 json 数组(大约 1500 个 JSON 对象),此外,当我获得大约 250 个 JSON 对象时,它的工作效果很好。

应用获取 JSON 数组并使用 Custome adatper 将其添加到 LIstView。

创建时:

try {
async_get_songs = new Read_today_songs();
async_get_songs.execute();
asynk_timeout(async_get_songs, 15000);
} catch (Exception e) {
    new Read_today_songs().execute();
}

异步任务:

public class Read_today_songs extends AsyncTask<String, Integer, String> {
        boolean running = true;

        @Override
        protected void onCancelled() {
            super.onCancelled();
            finish();
        }


        @Override
        protected String doInBackground(String... params) {
            try {
                jsonArray = getJSONs_array();
                if (jsonArray.length() > 0) {
                    today_song_item = new ArrayList<Map<String, String>>();
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        // singerName = jsonObject.getString("singerName");
                        Map<String, String> map = new HashMap<String, String>();

                        String singerName_coverted = jsonObject.getString("singerName").replaceAll("(\\r|\\n|' ')", "");
                        String songName_coverted = jsonObject.getString("songName").replaceAll("(\\r|\\n|' ')", "");
                        String date_coverted = jsonObject.getString("date").replaceAll("(\\r|\\n|' ')", "");

                        map.put("singerName", singerName_coverted);
                        map.put("songName", songName_coverted);
                        map.put("date", date_coverted);
                        today_song_item.add(map);
                    }
                    return "true";
                } else
                    return "false";
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            pbPlaylist.setVisibility(View.GONE);
            etSearchPlaylist.setEnabled(true);
            // check if got the today_song_itemArrayList<Map<String, String>>()
            // with values
            if (result.contains("true")) {
                ArrayList<Song> mListItems = new ArrayList<Song>();
                for (Map<String, String> mapItem : today_song_item) {
                    Song song_item = new Song(mapItem.get("singerName"), mapItem.get("songName"), mapItem.get("date"));
                    mListItems.add(song_item);
                }

                mAdapter = new CustomAdapter(thePlayList.this, R.layout.playlist_item_layout, mListItems);
                lvSongsList.setAdapter(mAdapter);
            } else
                fb_msg = "שגיאה התרחשה!";
        }
    }

public JSONArray getJSONs_array() throws ClientProtocolException, IOException, JSONException {
        StringBuilder url = new StringBuilder(current_url);
        HttpGet get = new HttpGet(url.toString());
        HttpResponse r = client.execute(get);
        int status = r.getStatusLine().getStatusCode();
        if (status == 200) {
            HttpEntity e = r.getEntity();
            String data = EntityUtils.toString(e);
            JSONArray JSONarray = new JSONArray(data);
            return JSONarray;
        } else
            return null;
    }

CustomeAdatper:

public class CustomAdapter extends ArrayAdapter<Song> {

    public CustomAdapter(Context context, int resource, ArrayList<Song> mlist) {
        super(context, resource);
        dbTools = new DBTools(context);
        this.mlist = mlist;
        this.context = context;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getPosition(Song item) {
        return super.getPosition(item);
    }

    @Override
    public Song getItem(int position) {
        return mlist.get(position);
    }

    @Override
    public int getCount() {
        return mlist.size();
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        convertView = inflater.inflate(R.layout.playlist_item_layout, null);// Replace your                         // layout....
        tvArtist = (TextView) convertView.findViewById(R.id.tvArtist);
        tvSongName = (TextView) convertView.findViewById(R.id.tvSongName);
        tvDate = (TextView) convertView.findViewById(R.id.tvDate);
        ivFav = (ImageView)convertView.findViewById(R.id.ivFav);

        tvArtist_from_list = mlist.get(position).getSingerName();
        tvSongName_from_list = mlist.get(position).getSongName();
        tvDate_from_list = mlist.get(position).getDate();

        tvArtist_from_list = tvArtist_from_list.replaceAll("(\\r|\\n|' ')", "");
        tvSongName_from_list = tvSongName_from_list.replaceAll("(\\r|\\n|' ')", "");
        tvDate_from_list = tvDate_from_list.replaceAll("(\\r|\\n|' ')", "");

        tvArtist.setText(tvArtist_from_list);
        tvSongName.setText(tvSongName_from_list);
        tvDate.setText(tvDate_from_list);

        try {
            Cursor c = dbTools.getAllRowsByQuery("SELECT * FROM favs WHERE singerName='"+tvArtist_from_list+"' AND songName='"+tvSongName_from_list+"'");
            if (c.moveToFirst()) {
                ivFav.setImageResource(R.drawable.plank4);
                ivFav.setTag("full");
            }else{
                ivFav.setImageResource(R.drawable.plank4_empty);
                ivFav.setTag("");
            }
        } catch (Exception e) {
            alert(e.toString());

        }
        return convertView;
    }
    // Filter Class
    public void filter(CharSequence cs) {
        String cs_string = String.valueOf(cs);
        cs_string = cs_string.toLowerCase(Locale.getDefault());
        if (original_mlist==null) {
            original_mlist = new ArrayList<Song>();
            original_mlist.addAll(mlist);
        }
        this.mlist.clear();
        if (cs_string.length() == 0) {
            mlist.addAll(original_mlist);

        } else {
            for (Song song_item : original_mlist) {
                if (son

g_item.getFullSongName().toLowerCase(Locale.getDefault()).contains(cs_string) ||
                            song_item.getSingerName().toLowerCase(Locale.getDefault()).contains(cs_string) ||
                            song_item

.getDate().toLowerCase(Locale.getDefault()).contains(cs_string)) {
                        this.mlist.add(song_item);
                    }
                }
            }
                notifyDataSetChanged();
            }
            public void alert(String get_fb_msg) {
                Toast.makeText(context, get_fb_msg, Toast.LENGTH_SHORT).show();
            }

    }

控制台错误:

04-01 18:49:50.082: E/AndroidRuntime(31326): FATAL EXCEPTION: main
04-01 18:49:50.082: E/AndroidRuntime(31326): java.lang.NullPointerException
04-01 18:49:50.082: E/AndroidRuntime(31326):    at com.manishma.thePlayList$Read_today_songs.onPostExecute(thePlayList.java:383)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at com.manishma.thePlayList$Read_today_songs.onPostExecute(thePlayList.java:1)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.os.AsyncTask.finish(AsyncTask.java:631)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.os.Looper.loop(Looper.java:137)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at android.app.ActivityThread.main(ActivityThread.java:5171)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at java.lang.reflect.Method.invokeNative(Native Method)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at java.lang.reflect.Method.invoke(Method.java:511)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
04-01 18:49:50.082: E/AndroidRuntime(31326):    at dalvik.system.NativeStart.main(Native Method)

我该如何解决?

【问题讨论】:

  • PlayList 中 AsyncTask 的第 383 行是什么(出现空指针的位置)
  • 不错!因为我返回了 null,所以将其更改为“none”,但有时它仍然没有接收到数据 - 我正在清除列表。是什么原因造成的?
  • 好像和json数组的元素个数没有关系。我的猜测是,您要检索的任何元素都有一个缺失字段,这会导致 nullPointerException,但如果不知道异常被抛出的确切行,就很难说。
  • 好的,所以我更改了 catch 以返回异常,这是我在没有接收数据时得到的: JSONException: Value 1 of type java.lang.integer cannot be convert to JSONArray

标签: android arrays json android-asynctask


【解决方案1】:

使用IntentService 而不是 AsyncTask,服务不依赖于您的活动或片段的生命周期,它们具有独立的生命周期,例如,如果您在活动中创建异步任务并且用户旋转他们的设备,将重新创建 AsyncTask 并将重新开始,而不是如果您使用 IntentService,一旦网络请求开始,无论用户更改方向或切换应用程序都无关紧要,请求将完成;然后你要做的是找出如何通知你的活动/片段有新数据可用,你可以使用广播,或者使用外部库,如Otto

由于 json 如此之大,最好将其存储在本地并仅在您知道某些内容已更改或经过很长时间后才获取它

【讨论】:

  • 您能解释一下为什么 IntentService 是更好的选择吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2022-06-13
  • 1970-01-01
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
相关资源
最近更新 更多