簡體   English   中英

如果無法使用互聯網,則應用崩潰-Android

[英]App crashes if Internet is not available - Android

我正在從服務器加載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);
    }
}

為了防止崩潰,您應該檢查設備是否可以連接互聯網,您可以使用以下方法:

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消息,那么也許我可以告訴您更多有關您的問題的信息。

您的問題是,在捕獲Internet異常時您將返回空的arraylist。 因此, onPostExecute空,然后適配器為空。

如果您不希望使用null值,請預先聲明一個空列表並始終返回它。

然后,該應用程序將不會崩潰,但是列表中將看不到任何數據,因此您可能需要進行一些其他驗證,以確保互聯網可用。

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

    List<MovieModel> movieModelList = new ArrayList<>();

    try {
        // TODO: Stuff

        return movieModelList;
    } catch ( ... ) {

    } finally {

    }

    return movieModelList;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM