2016-07-16 11 views
0

Ich habe eine ListView, die den gesuchten Titel des Films von OMDBAPI zeigt und wenn Sie auf die Suche btn klicken, muss ich zweimal anstelle von einmal klicken.JSONParser zu ListView brauchen doppelte

Bitte Hilfe.

Hier ist der Code:

public class JSONParser extends AsyncTask<String, String, String> { 

    static ArrayList<String> movieList = new ArrayList<>(); 

    @Override 
    protected String doInBackground(String... params) { 

     HttpURLConnection httpURLConnection = null; 
     BufferedReader reader = null; 
     StringBuilder builder = new StringBuilder(); 

     try { 

      URL url = new URL(params[0]); 
      httpURLConnection = (HttpURLConnection) url.openConnection(); 
      httpURLConnection.connect(); 
      InputStream stream = httpURLConnection.getInputStream(); 
      reader = new BufferedReader(new InputStreamReader(stream)); 
      String line = ""; 
      while ((line = reader.readLine()) != null){ 
       builder.append(line); 

      } 
      return builder.toString(); 


     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     finally { 
      if(httpURLConnection != null){ 
       httpURLConnection.disconnect(); 
      } 
      try { 
       if (reader != null){ 
        reader.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     return "Failed Connection"; 
    } 



    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 

     try { 
      JSONObject jsonObject = new JSONObject(result); 
      JSONArray jsonArray = jsonObject.getJSONArray("Search"); 
      StringBuilder stringBuilder = new StringBuilder(); 
      for (int i = 1; i<jsonArray.length(); i++){ 
       JSONObject finalJsonObject = jsonArray.getJSONObject(i); 
       String titleOfMovie = finalJsonObject.getString("Title"); 
       movieList.add(titleOfMovie); 
       stringBuilder.append(movieList); 
       finalJsonObject.get("Title"); 

      } 


     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

Hier ist der mainActivivty:

public class Main2ActivityWeb extends AppCompatActivity { 

    EditText searchBar; 
    ListView listOfMovies; 
    Button searchBtn; 
    Button deleteBtn; 
    ArrayAdapter<String> arrayAdapter; 
    String url = "http://www.omdbapi.com/?s="; 

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

     searchBar = (EditText) findViewById(R.id.etsearch); 
     listOfMovies = (ListView) findViewById(R.id.lvMovies); 
     searchBtn = (Button) findViewById(R.id.btnSearch); 
     deleteBtn = (Button) findViewById(R.id.btnClear); 

     searchBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       arrayAdapter = null; 
       final String search = url + searchBar.getText().toString(); 
       new JSONParser().execute(search); 
       ArrayList<String> list = new ArrayList<>(JSONParser.movieList); 
       arrayAdapter = new ArrayAdapter<>(Main2ActivityWeb.this, 
         android.R.layout.simple_list_item_1, list); 
       listOfMovies.setAdapter(arrayAdapter); 
       if (arrayAdapter !=null){ 
        JSONParser.movieList.clear(); 
       } 



      } 
     }); 

     deleteBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       listOfMovies.setAdapter(null); 
       JSONParser.movieList.clear(); 
       searchBar.setText(""); 
      } 
     }); 


    } 
} 
+0

Verwenden Volley des JSONObjectRequest. Viel einfacher als die Verwendung einer AsyncTask. –

Antwort

0

Ihr Problem ist, dass Sie scheinen nicht, das Konzept zu verstehen, dass ein AsyncTask asynchrone ist, so

new JSONParser().execute(search); 

Wird nichts in 01 gespeichertbis die onPostExecute abgeschlossen ist.

Inzwischen geht es weiter nach synchron Lauf

ArrayList<String> list = new ArrayList<>(JSONParser.movieList); 

die meist wahrscheinlich leer das erste Mal, wenn Sie auf die Schaltfläche klicken, weil Sie immer noch warten auf die AsyncTask im Hintergrund zu beenden, die JSON zu analysieren.

Auf den zweiten Klick der Schaltfläche, Sie starten eine neue Anfrage für die JSON, aber die Ergebnisse, die Sie sehen, sind von der ersten Anfrage.


Eine Möglichkeit, das zu lösen ist Rückrufe, wie Volley, Retrofit/OkHttp tun würde, aber Sie können auch um die Objekte, die Sie so verwenden bewegen, dass sie in der richtigen Reihenfolge auszuführen. Zum Beispiel, es hält den AsyncTask die ArrayAdapter geben, anstatt es zu mit seiner eigenen Arraylist

private ArrayList<String> list; 

... 

onCreate() { 
    listOfMovies = (ListView) findViewById(R.id.lvMovies); 
    list = new ArrayList<>(); 
    arrayAdapter = new ArrayAdapter<>(Main2ActivityWeb.this, 
         android.R.layout.simple_list_item_1, list); 
    listOfMovies.setAdapter(arrayAdapter); 

... 
    onClick() { 
     ... 
     new JSONParser(arrayAdapter).execute(search); 
    } 
} 

Im AsyncTask

public class JSONParser extends AsyncTask<String, String, String> { 

    private ArrayAdapter<String> adapter; 

    public JSONParser(ArrayAdapter<String> adapter) { 
     this.adapter = adapter; 
    } 

    ... 

    onPostExectute() { 
     for (...) { 
      adapter.add(titleOfMovie); 
     } 
     apdater.notifyDataSetChanged(); 
    } 
}