doInBackground()上的AsyncTask String.length()null对象引用

时间:2017-05-19 19:12:01

标签: java android json android-asynctask nullreferenceexception

也许你可以帮助我。我的应用程序允许您将movieID中的movieID保存到SQLiteDatabase。我能够成功检索movieID和userID。当为电影发送API请求时,日志显示它也成功返回,但我不断收到以下错误,应用程序重新启动或崩溃。

  05-19 18:43:10.118 8103-8103/? W/PathParser: Points are too far apart 4.000000596046461
05-19 18:43:15.263 2407-2626/? I/ActivityManager: START u0 {flg=0x10000 cmp=com.example.asc.app/.MovieList} from uid 10058 on display 0
05-19 18:43:15.283 8103-8103/? W/PathParser: Points are too far apart 4.000000596046461
05-19 18:43:15.293 8103-8103/? D/MovieList:: movie_user_id1
05-19 18:43:17.222 8103-8651/? W/System.err: java.io.FileNotFoundException: https://api.themoviedb.org/3/movie/278?api_key=b5c3cfd30f424540a36db95684a067e0
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:238)
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.example.asc.app.MovieHttpClient.getMovieData(MovieHttpClient.java:43)
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.example.asc.app.MovieAsyncTask.doInBackground(MovieAsyncTask.java:21)
05-19 18:43:17.222 8103-8651/? W/System.err:     at com.example.asc.app.MovieAsyncTask.doInBackground(MovieAsyncTask.java:13)
05-19 18:43:17.222 8103-8651/? W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:295)
05-19 18:43:17.222 8103-8651/? W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-19 18:43:17.222 8103-8651/? W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
05-19 18:43:17.222 8103-8651/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
05-19 18:43:17.222 8103-8651/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
05-19 18:43:17.222 8103-8651/? W/System.err:     at java.lang.Thread.run(Thread.java:818)
05-19 18:43:17.223 8103-8103/? W/System.err: java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
05-19 18:43:17.223 8103-8103/? W/System.err:     at java.util.concurrent.FutureTask.report(FutureTask.java:94)
05-19 18:43:17.223 8103-8103/? W/System.err:     at java.util.concurrent.FutureTask.get(FutureTask.java:164)
05-19 18:43:17.223 8103-8103/? W/System.err:     at android.os.AsyncTask.get(AsyncTask.java:498)
05-19 18:43:17.223 8103-8103/? W/System.err:     at com.example.asc.app.MovieList.populateList(MovieList.java:106)
05-19 18:43:17.223 8103-8651/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                                                 Process: com.example.asc.app, PID: 8103
                                                 java.lang.RuntimeException: An error occurred while executing doInBackground()
                                                     at android.os.AsyncTask$3.done(AsyncTask.java:309)
                                                     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                                                     at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                                                     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                     at java.lang.Thread.run(Thread.java:818)
                                                  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
                                                     at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
                                                     at org.json.JSONTokener.nextValue(JSONTokener.java:94)
                                                     at org.json.JSONObject.<init>(JSONObject.java:156)
                                                     at org.json.JSONObject.<init>(JSONObject.java:173)
                                                     at com.example.asc.app.JSONMovieParser.getMovie(JSONMovieParser.java:19)
                                                     at com.example.asc.app.MovieAsyncTask.doInBackground(MovieAsyncTask.java:26)
                                                     at com.example.asc.app.MovieAsyncTask.doInBackground(MovieAsyncTask.java:13)
                                                     at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                     at java.lang.Thread.run(Thread.java:818) 

MovieList.java - 我想要显示的地方

public class MovieList extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener{

dbOpenHelper helper = new dbOpenHelper(this);
int movieID = -1;
int userID = 1;
String title = "MLTitle";
String posterPath = "MLPosterPath";
private ArrayAdapter<String> listAdapter ;

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.nav_movielist);

    populateList();
}

public void populateList() {

    SQLiteDatabase database = helper.getWritableDatabase();
    userID = ((ApplicationSession) getApplication()).getUserID();

    String[] projection = {
            helper.MOVIE_USER_ID,
            helper.MOVIE_REF_ID,
            helper.MOVIE_TITLE,
            helper.MOVIE_POSTER_PATH
    };

    String selection = helper.MOVIE_USER_ID + " = ?";
    String[] selectionArgs = {Integer.toString(userID)};
    Log.d("MovieList: ", helper.MOVIE_USER_ID+userID); //Displays correct user id
    Cursor cursor = database.query(
            helper.TABLE_MOVIES,                     // The table to query
            projection,                               // The columns to return
            selection,                                // The columns for the WHERE clause
            selectionArgs,                            // The values for the WHERE clause
            null,                                     // don't group the rows
            null,                                     // don't filter by row groups
            null                                 // The sort order
    );

    if (cursor.moveToFirst()){
        do{
            movieID = cursor.getInt(cursor.getColumnIndex("movie_ref_id"));
            MovieAsyncTask task = new MovieAsyncTask();
            try {
                boolean search = false;
                String searchString = Integer.toString(movieID);
                JSONObject object  = task.execute(searchString, search).get();

                List<String> titlesList = new ArrayList<>();
                List<String> posterpathList = new ArrayList<>();
                ListView movieList =  (ListView) findViewById(R.id.lstMovies);

                final int numberOfItemsInResp = object.length();
                for(int i = 0; i < numberOfItemsInResp; i++)
                {
                    try{
                       title = object.get("title").toString();
                       posterPath = object.get("poster_path").toString();
                    }
                    catch (JSONException e) {
                        e.printStackTrace();
                    }
                    //FILL LIST HERE
                    titlesList.add(title);
                    posterpathList.add(posterPath);
                }
                movieList.setAdapter( listAdapter );

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }while(cursor.moveToNext());
    }
    cursor.close();
}

MovieAsyncTask.java

public class MovieAsyncTask extends AsyncTask<Object, Void, JSONObject> {

@Override
protected JSONObject doInBackground(Object... params) {

    String searchString = (String) params[0];
    boolean search = (boolean) params[1];

    String data = ( (new MovieHttpClient()).getMovieData(searchString, search));

    JSONObject jObj = new JSONObject();
    try {

        jObj = JSONMovieParser.getMovie(data);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return jObj;
}
}

MovieHTTPClient.java

public class MovieHttpClient {

private static final String API_KEY = "?api_key=b5c3cfd30f424540a36db95684a067e0";
private static final String BASE_URL = "https://api.themoviedb.org/3/";
private static final String SEARCH = "search/movie";
private static final String MOVIE = "movie/";
private static final String QUERY = "&query=";

public String getMovieData(String searchString, boolean search) {

    HttpURLConnection con = null ;
    InputStream is = null;
    String url;

    try {
        if (search) {
            url = BASE_URL + SEARCH + API_KEY + QUERY;
            url += searchString;
        }else{
            url = BASE_URL + MOVIE + searchString + API_KEY;
        }
        con = (HttpURLConnection) (new URL(url)).openConnection();
        con.setRequestMethod("GET");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.connect();

        StringBuffer buffer = new StringBuffer();
        is = con.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = br.readLine()) != null)
            buffer.append(line + "\r\n");

        is.close();
        con.disconnect();

        return buffer.toString();
    }
    catch(Throwable t) {
        t.printStackTrace();
    }
    finally {
        try { is.close(); } catch(Throwable t) {}
        try { con.disconnect(); } catch(Throwable t) {}
    }
    return null;
}
}

编辑1:btnSearch

 btnSearch.setOnClickListener(new android.view.View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            String searchString = txtSearch.getText().toString();
            TextView tvTitle = (TextView) findViewById(R.id.tvTitle);
            TextView tvRating = (TextView) findViewById(R.id.tvRating);
            TextView tvReleaseDate = (TextView) findViewById(R.id.tvReleaseDate);
            TextView tvOverview = (TextView) findViewById(R.id.tvOverview);
            ImageView imgVPoster = (ImageView) findViewById(R.id.imgVPoster);
            boolean search = true;

            MovieAsyncTask task = new MovieAsyncTask();
            try {
                JSONObject object  = task.execute(searchString, search).get();
                //String title = "title";
                //String posterPath = "poster Path";
                String rating = "rating";
                String releaseDate = "release Date";
                String overview = "overview";

                final int numberOfItemsInResp = object.length();
                for(int i = 0; i < numberOfItemsInResp; i++)
                {
                    try{
                        title = object.get("title").toString();
                        movieID = (object.getInt("id"));
                        posterPath = object.get("poster_path").toString();
                        rating = object.get("vote_average").toString();
                        releaseDate = object.get("release_date").toString();
                        overview = object.get("overview").toString();
                    }
                    catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                String urlStr = BASE_URL + FILE_SIZE + posterPath;
                tvTitle.setText(title);
                tvRating.setText("Rating: " + rating + "/10");
                tvReleaseDate.setText("Released: " + releaseDate);
                tvOverview.setText("Plot \n" + overview);

                new SetPosterTask((ImageView) findViewById(R.id.imgVPoster))
                        .execute(urlStr);
                imgVPoster.setVisibility(View.VISIBLE);
                ibtnOff.setVisibility(View.VISIBLE);
                Log.d("MovieDetails", urlStr);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    });

1 个答案:

答案 0 :(得分:0)

您立即在AsyncTask上调用了.get()。它将为null,因为它对FutureTask还没有响应。然后,您检查了该空值的长度。

EKEvent *event = [EKEvent eventWithEventStore:store];
EKAlarm *alarmForOneDayBeforeAppointment = [[EKAlarm alloc] init];
alarmForOneDayBeforeAppointment.absoluteDate = [self modifyDate:eventDate
                                                       withUnit:NSCalendarUnitDay
                                                                 andQuantity:-1];
event.alarms = @[alarmForOneDayBeforeAppointment];
[store saveEvent:event span:EKSpanThisEvent error:&err];

您需要在另一个线程中获取任务后的任务结果。 AsyncTask为它提供了帮助位,它将在UI线程完成后返回结果。