【问题标题】:App crashes if Internet is not available - Android如果互联网不可用,应用程序崩溃 - Android
【发布时间】:2016-08-11 22:18:55
【问题描述】:

我正在从服务器加载 JSON,但如果互联网不可用,应用程序会崩溃。如何解决这个问题?我在大多数情况下都添加了 try catch。无法找到问题。 lvMovies.setAdapter(adapter); 在互联网不可用时给出错误。当互联网可用时,代码可以正常工作

public class JSONTest extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    private ListView lvMovies;
    private ProgressDialog dialog;
    private SwipeRefreshLayout swipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jsontest);

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeMovieHits);
        swipeRefreshLayout.setOnRefreshListener(this);

        // Create default options which will be used for every
        //  displayImage(...) call if no options will be passed to this method
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultOptions)
                .build();
        ImageLoader.getInstance().init(config); // Do it on Application start

        lvMovies = (ListView) findViewById(R.id.lvMovies);
        dialog = new ProgressDialog(this);
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.setMessage("Loading...");
        //new JSONTask().execute("http://ankushkapoor2016.16mb.com/ankush/myjson.txt");
        //new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesDemoList.txt");
    }

    @Override
    public void onRefresh() { //SwipeRefreshLayout Refresh Listener
        try {
            new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesData.txt");
        } catch (Exception e) {
            Toast.makeText(JSONTest.this, e.getMessage() + "\n\n" + e.getCause(), Toast.LENGTH_LONG).show();
        }
    }

    public class JSONTask extends AsyncTask<String, String, List<MovieModel>> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog.show();
        }

        @Override
        protected List<MovieModel> doInBackground(String... params) {

            HttpURLConnection connection = null;
            BufferedReader reader = null;

            try {
                URL url = new URL(params[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();

                InputStream stream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(stream));

                StringBuffer buffer = new StringBuffer();
                String line = "";
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }

                String finalJson1 = buffer.toString();

                SharedPreferences sharedPreferences = getSharedPreferences("JSON_DATA", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putString("json", finalJson1);
                editor.commit();

                String finalJson=sharedPreferences.getString("json","N/A");

                JSONObject parentObject = new JSONObject(finalJson);
                JSONArray parentArray = parentObject.getJSONArray("movies");

                List<MovieModel> movieModelList = new ArrayList<>();
                for (int i = 0; i < parentArray.length(); i++) {
                    JSONObject finalObject = parentArray.getJSONObject(i);
                    MovieModel movieModel = new MovieModel();
                    movieModel.setMovie(finalObject.getString("movie"));
                    movieModel.setYear(finalObject.getInt("year"));
                    movieModel.setRating((float) finalObject.getDouble("rating"));
                    movieModel.setDuration(finalObject.getString("duration"));
                    movieModel.setDirector(finalObject.getString("director"));
                    movieModel.setTagline(finalObject.getString("tagline"));
                    movieModel.setImage(finalObject.getString("image"));
                    movieModel.setStory(finalObject.getString("story"));

                    List<MovieModel.Cast> castList = new ArrayList<>();
                    for (int j = 0; j < finalObject.getJSONArray("cast").length(); j++) {
                        MovieModel.Cast cast = new MovieModel.Cast();
                        cast.setName(finalObject.getJSONArray("cast").getJSONObject(j).getString("name"));
                        castList.add(cast);
                    }
                    movieModel.setCastList(castList);
                    movieModelList.add(movieModel);
                }
                return movieModelList;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } finally {
                if (connection != null)
                    connection.disconnect();
                try {
                    if (reader != null)
                        reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return null;
        }

        @Override
        protected void onPostExecute(List<MovieModel> s) {
            super.onPostExecute(s);
            dialog.dismiss();
            MovieAdapter adapter = new MovieAdapter(getApplicationContext(), R.layout.row, s);
            lvMovies.setAdapter(adapter);
            if (swipeRefreshLayout.isRefreshing()) {
                swipeRefreshLayout.setRefreshing(false);
            }
        }
    }

    public class MovieAdapter extends ArrayAdapter {

        private List<MovieModel> movieModelList;
        private int resource;
        private LayoutInflater inflater;

        public MovieAdapter(Context context, int resource, List<MovieModel> objects) {
            super(context, resource, objects);
            movieModelList = objects;
            this.resource = resource;
            inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(resource, null);
                holder.ivMovieIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
                holder.tvMovie = (TextView) convertView.findViewById(R.id.tvMovie);
                holder.tvTagline = (TextView) convertView.findViewById(R.id.tvTagline);
                holder.tvYear = (TextView) convertView.findViewById(R.id.tvYear);
                holder.tvDuration = (TextView) convertView.findViewById(R.id.tvDuration);
                holder.tvDirector = (TextView) convertView.findViewById(R.id.tvDirector);
                holder.rbMovieRating = (RatingBar) convertView.findViewById(R.id.rbMovie);
                holder.tvCast = (TextView) convertView.findViewById(R.id.tvCast);
                holder.tvStory = (TextView) convertView.findViewById(R.id.tvStory);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            final ProgressBar progressBar;
            progressBar = (ProgressBar) convertView.findViewById(R.id.progressBar);

            try {
                ImageLoader.getInstance().displayImage(movieModelList.get(position).getImage(), holder.ivMovieIcon, new ImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                        progressBar.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                        progressBar.setVisibility(View.GONE);
                    }

                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                        progressBar.setVisibility(View.GONE);
                    }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) {
                        progressBar.setVisibility(View.GONE);
                    }
                });
                holder.tvMovie.setText(movieModelList.get(position).getMovie());
                holder.tvTagline.setText(movieModelList.get(position).getTagline());
                holder.tvYear.setText("Year: " + movieModelList.get(position).getYear());
                holder.tvDuration.setText(movieModelList.get(position).getDuration());
                holder.tvDirector.setText(movieModelList.get(position).getDirector());

                holder.rbMovieRating.setRating(movieModelList.get(position).getRating() / 2);


                StringBuffer stringBuffer = new StringBuffer();
                for (MovieModel.Cast cast : movieModelList.get(position).getCastList()) {
                    stringBuffer.append(cast.getName() + ", ");
                }
                holder.tvCast.setText(stringBuffer);
                holder.tvStory.setText(movieModelList.get(position).getStory());
            } catch (Exception e) {
                Toast.makeText(getContext(), e.getMessage() + "\n" + e.getCause(), Toast.LENGTH_SHORT).show();
            }
            return convertView;
        }

        class ViewHolder {
            private ImageView ivMovieIcon;
            private TextView tvMovie;
            private TextView tvTagline;
            private TextView tvYear;
            private TextView tvDuration;
            private TextView tvDirector;
            private RatingBar rbMovieRating;
            private TextView tvCast;
            private TextView tvStory;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_json, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.jsonRefresh) {
            try {
                new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesData.txt");
                return true;
            } catch (Exception e) {
                Toast.makeText(JSONTest.this, e.getMessage() + "\n\n" + e.getCause(), Toast.LENGTH_LONG).show();
            }
        }
        return super.onOptionsItemSelected(item);
    }
}

【问题讨论】:

  • 请添加您的日志输出。

标签: android android-json android-internet


【解决方案1】:

为了防止崩溃,你应该检查设备是否有互联网连接,你可以使用:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
      = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

您还需要添加到您的 AndroidManifest:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

如果你提供 logcat 消息,那么也许我可以告诉你更多关于你的问题。

【讨论】:

    【解决方案2】:

    你的问题是当互联网异常被捕获时你返回一个空数组列表。因此,onPostExecute 变为空,然后适配器变为空。

    如果您不想要空值,请预先声明一个空列表并始终返回它。

    然后,应用程序不会崩溃,但您不会在列表中看到任何数据,因此您可能需要做一些额外的验证以确保互联网可用。

    @Override
    protected List<MovieModel> doInBackground(String... params) {
    
        List<MovieModel> movieModelList = new ArrayList<>();
    
        try {
            // TODO: Stuff
    
            return movieModelList;
        } catch ( ... ) {
    
        } finally {
    
        }
    
        return movieModelList;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-13
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 2016-06-09
      相关资源
      最近更新 更多