android中的JSON解析和获取图像

Posted

技术标签:

【中文标题】android中的JSON解析和获取图像【英文标题】:JSON parsing and getting images in android 【发布时间】:2016-09-10 04:03:26 【问题描述】:

我想解析包含字符串和图像的 JSON 对象。我的代码正在运行,但加载图像太慢了。我想用另一个异步任务或服务加载图像以减少加载时间。我怎样才能做到这一点?哪一种是使用 asynctask 或 service 的最佳方法?这是我的代码

public class Traffic extends Fragment 
private ListView listView;
private HttpURLConnection connection = null;
private BufferedReader bufferedReader = null;
private InputStream inputStream = null;
private ArrayList<TrafficModelClass> trafficList;
private TrafficAdapter trafficAdapter;
private View view;
private ProgressDialog progressDialog;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    view = inflater.inflate(R.layout.traffic,container,false);
    listView = (ListView) view.findViewById(R.id.trafficListView);
    progressDialog = ProgressDialog.show(view.getContext(),"" ,"Wait..." , true);
    new GetTrafficNews().execute();
    trafficList = new ArrayList<TrafficModelClass>();
    trafficAdapter = new TrafficAdapter(view.getContext() , R.id.trafficListView , trafficList);
    listView.setAdapter(trafficAdapter);
    return view;

public class GetTrafficNews extends AsyncTask<String , Void , String> 


    @Override
    protected String doInBackground(String... params) 
        try 
            URL url = new URL("http://www.dtexeshop.com/Journalist/GetTrafficNews.php");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoInput(true);
            inputStream = connection.getInputStream();
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
            StringBuffer stringBuffer = new StringBuffer();
            String line="";

            while((line=bufferedReader.readLine()) != null)
                stringBuffer.append(line);
            

            String finalJson = stringBuffer.toString();
            JSONObject parentJson = new JSONObject(finalJson);
            JSONArray parentJsonArray = parentJson.getJSONArray("traffic");

            for (int i = 0; i < parentJsonArray.length(); i++) 
                JSONObject finalJsonObject = parentJsonArray.getJSONObject(i);

                TrafficModelClass modelClass = new TrafficModelClass();
                modelClass.setUserName(finalJsonObject.getString("UserName"));
                modelClass.setDateTime(finalJsonObject.getString("DateTime"));
                modelClass.setHeadline(finalJsonObject.getString("Headline"));
                String string_url ="http://www.dtexeshop.com/Journalist/images/"+ finalJsonObject.getString("ImageName");
                URL urlImage = new URL(string_url);
                Bitmap image = BitmapFactory.decodeStream(urlImage.openConnection().getInputStream());
                modelClass.setBitmapImage(image);
                modelClass.setDescription(finalJsonObject.getString("Description"));

                trafficList.add(modelClass);
                if(i==1)
                    progressDialog.dismiss();
                
            
            inputStream.close();

         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (ProtocolException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
         catch (JSONException e) 
            e.printStackTrace();
        finally 
            if (connection != null) 
                connection.disconnect();
            
            if (bufferedReader != null) 
                try 
                    bufferedReader.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
        return null;
    

    @Override
    protected void onPreExecute() 
        super.onPreExecute();
    

    @Override
    protected void onPostExecute(String s) 
        trafficAdapter.notifyDataSetChanged();
        progressDialog.dismiss();
    

【问题讨论】:

【参考方案1】:

我建议你使用 picasso 库来获取图像,这对你来说是完美的。它不会延迟加载时间,它会根据网络加载图像。

只需使用这行代码:

Picasso.with(context).load("url").into(imageview);

并将此依赖项添加到您的应用程序中。

compile 'com.squareup.picasso:picasso:2.5.2'

【讨论】:

【参考方案2】:

首先,你不应该在非 UI 线程中调用 progressDialog.dismiss(),所有对 UI 组件的操作都应该在 UI 线程中完成。在我看来,最常见和最现代的方法是使用 RxJava 框架执行此类操作。它允许你以函数式的方式非常容易地编写这样的算法。但是一旦你熟悉了它,你就不想停止使用它。我的解决方案如下所示:

createDownloadObservable(url) // download json
    .map(json -> parseJson(json) // parse json text into a json object
    .map(jsonObject -> extractTrafficModel(jsonObject))) // extract list of TrafficModels from jsonObject
    .flatMap(trafficModelList -> Observable.from(trafficModelList)) // push every TrafficModel item in a pool
    .map(trafficModelItem -> downloadImage(trafficModelItem)) // download and set image for each TrafficModel item
    .toList() // aggreagate all items in a list
    .subscribe(new Subscriber() 
        public void onNext(List<TrafficModel> trafficModelList) 
            // here you are! You can do what you want to with this traffic model list
        

        public void onError(Throable e) 
            // if some error appeared while passing the algorithm, you can process it here
        
    )

【讨论】:

以上是关于android中的JSON解析和获取图像的主要内容,如果未能解决你的问题,请参考以下文章

Android 图片库 JSON / SQLite 带可变数量的图像

Android基础——JSON数据的全方位解析

同一个活动Android Studio中的两个JSON解析方法

JSON解析器获取图像

如何使用 android 解析 RecyclerView 中的 json?

Android JSON解析使用Web服务查看古吉拉特语字符