2017-05-19 11 views
-2

多分あなたが私を助けることができます。私のアプリケーションでは、APIからmovieIDをSQLiteDatabaseに保存することができます。 movieIDとuserIDを正常に取得できました。ムービーのAPIリクエストが送信されると、ログにも正常に返されたことが表示されますが、次のエラーが表示され続け、アプリケーションが再起動またはクラッシュします。AsyncTask on doInBackground()String.length()nullオブジェクト参照

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(); 
      } 
     } 
    }); 
+2

[NullPointerExceptionとは何ですか?それを修正するにはどうすればいいですか?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix -it) – Zoe

+0

実行後にget()を呼び出すと、Asynctaskの目的が無効になります。 –

+0

別のアクティビティでは、オブジェクトを取得するために同じ構造を使用しました。 btnSearchで更新されました。このインスタンスでなぜそれが動作するのか、またはAsynctasksを行う適切な方法を詳しく説明できますか? – Toxic

答えて

0

すぐにAsyncTaskで.get()を呼び出しました。 FutureTaskにまだ応答がないため、nullになります。あなたはそのヌルの長さをチェックしました。

JSONObject object = task.execute(searchString, search).get(); 
... 
final int numberOfItemsInResp = object.length(); 

タスクの結果を別のスレッドで取得する必要があります。 AsyncTaskは、終了後にUIスレッドで結果を返すヘルパービットを与えます。

関連する問題