저는 API (The Movie Database)를 취하는 Android 애플리케이션을 제작하고 JSON 배열을 추출합니다. 추출시 적절한 JSONObject가 모델로 전송됩니다. 이 모델은 객체를 추출하고 그것을 사용할 수있는 변수에 할당하는 setter와 getter로 구성된 클래스입니다. 이 모든 작업은 AsyncTask에서 수행됩니다. 그러나 뭔가를 반환 할 것으로 예상대로 doInBackground 메서드를 이해하는 데 어려움을 겪고 있습니다. getMovieJson 메서드에 대한 모든 작업을 완료했으며 onPostExecute 메서드에서 내 사용자 지정 어댑터를 업데이트해야하므로 doInBackground에서 무언가를 반환해야한다는 것을 알고 있습니다. 이 사용자 지정 어댑터는 myView에 채울 적절한 뷰를 만드는 ArrayAdapter입니다. AsyncTask에서 사용자 정의 ArrayList를 구현하는 방법은 무엇입니까?
이
내 모델package com.xxcanizeusxx.erick.moviesnow;
/**
* This class acts as the model base for our
* array of JSON Objects that need to be populated.\
* This class uses getters and setters to achieve its task.
*/
public class Movie {
private String title;
private String vote_average;
private String overview;
private String release_date;
private String poster_path;
public String getTitle(){
return title;
}
public void setTitle(String title){
this.title = title;
}
public String getOverview(){
return overview;
}
public void setOverview(String overview){
this.overview = overview;
}
public String getRelease_date(){
return release_date;
}
public void setRelease_date(String release_date){
this.release_date = release_date;
}
public String getVote_average(){
return vote_average;
}
public void setVote_average(String vote_average){
this.vote_average = vote_average;
}
public String getPoster_path(){
return poster_path;
}
public void setPoster_path(String poster_path){
this.poster_path = poster_path;
}
}
이 내 조각이다
package com.xxcanizeusxx.erick.moviesnow;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
/**
* Created by Erick on 1/4/2017.
*/
public class MovieFragment extends Fragment {
//Initialize our array adapter and components.
private ArrayList<Movie> mMovieData;
private MovieAdapter mMovieAdapter;
//Empty constructor
public MovieFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.movie_fragment, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.popular_movies) {
updateMovie();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateMovie() {
FetchMovieTask fetchMovie = new FetchMovieTask();
fetchMovie.execute();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Initialize our array adapter
mMovieData = new ArrayList<>();
mMovieAdapter = new MovieAdapter(getActivity(), R.layout.grid_movie_item, mMovieData);
View rootView = inflater.inflate(R.layout.gird_layout, container, false);
//Get a reference to the gridView and attach the adapter to it
GridView mGridView = (GridView) rootView.findViewById(R.id.gridView);
mGridView.setAdapter(mMovieAdapter);
return rootView;
}
@Override
public void onStart() {
super.onStart();
updateMovie();
}
public class FetchMovieTask extends AsyncTask<String[], Void, String[]> {
private final String LOG = FetchMovieTask.class.getSimpleName();
private String[] getMovieJson(String movieJsonStr) throws JSONException {
final String OWM_RESULTS = "results";
String title;
String posterPath;
JSONObject movieJson = new JSONObject(movieJsonStr);
JSONArray movieJsonArray = movieJson.getJSONArray(OWM_RESULTS);
Movie movieItem = new Movie();
//Newly created array that will house the data in order to check for views on the onPostExecute method
String[] results = new String[movieJsonStr.length()];
for (int i = 0; i < movieJsonArray.length(); i++) {
JSONObject movieObject = movieJsonArray.getJSONObject(i);
title = movieObject.getString("title");
posterPath = movieObject.getString("poster_path");
movieItem.setTitle(title);
movieItem.setPoster_path(posterPath);
results[i] = movieObject.getString(posterPath) +" " + movieObject.getString(posterPath);
}
mMovieData.add(movieItem);
return results;
}
@Override
protected String[] doInBackground(String[]... params) {
//Establish a connection
HttpURLConnection urlConnection = null;
BufferedReader bufferedReader = null;
//Will contain the raw JSON as a string
String movieJsonStr = null;
//String as placeholders
String descriptionHolder = "popularity.desc";
try {
//String to hold the Base url
final String TMDB_BASE_URL = "http://api.themoviedb.org/3/discover/movie?";
final String APPID = "api_key";
final String DESC = "sort_by";
//Build the url
Uri buildMovieUri = Uri.parse(TMDB_BASE_URL).buildUpon()
.appendQueryParameter(DESC, descriptionHolder)
.appendQueryParameter(APPID, BuildConfig.TMDP_API_KEY)
.build();
URL url = new URL(buildMovieUri.toString());
//Create the request to TMDB and open connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
//Read the input stream into a string
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
//Nothing to do
return null;
}
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
//Make debugging easier by adding a new line to the bufffer stream
buffer.append(line + "\n");
int result = 1;
}
if (buffer.length() == 0) {
//stream was empty. No point in parsing.
return null;
}
movieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG, "Error ", e);
//If code didnt get the movie data, no point in parsing
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (final IOException e) {
Log.e(LOG, "Error closing stream ", e);
}
}
}
try {
return getMovieJson(movieJsonStr);
} catch (JSONException e) {
Log.e(LOG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String[] result){
if (result != null){
mMovieAdapter.clear();
for (String results : result ){
mMovieAdapter.setMovieData(results);
}
}
}
}
}
이이 나의 주요 활동 내 어댑터
package com.xxcanizeusxx.erick.moviesnow;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
/**
* This class is the MovieAdapter that will take data from the model and
* display it on the View. Additionally, this adapter will load the picasso base_img_url
* to populate the griView according to Udacity.
*/
public class MovieAdapter extends ArrayAdapter<Movie> {
private final String BASE_IMAGE_URL = "http://image.tmdb.org/t/p/w185";
private Context mContext;
private int resource;
private ArrayList<Movie> mMovieData = new ArrayList<Movie>();
//Constructor matching super
public MovieAdapter(Context mContext, int resource, ArrayList<Movie> mMovieData) {
super(mContext, resource, mMovieData);
this.mContext = mContext;
this.resource = resource;
this.mMovieData = mMovieData;
}
//This method sets the movieData and refreshes the gridLayout items.
public void setMovieData(ArrayList<Movie> mMovieData){
this.mMovieData = mMovieData;
//Notifies if data state has changed
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//Declare the variables to hold the convertView and viewHolder static class
View cv = convertView;
ViewHolder viewHolder;
//If the convertView is null, we don't have a view so, create one.
if(cv == null){
//Create the View
cv = LayoutInflater.from(getContext()).inflate(resource, parent, false);
//Call the static viewHolder class
viewHolder = new ViewHolder();
//Initialize the textView and imageView to load inside the view
viewHolder.movieTextView = (TextView) cv.findViewById(R.id.movie_title);
viewHolder.moviePoster = (ImageView) cv.findViewById(R.id.movie_poster);
cv.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) cv.getTag();
}
Movie movieItem = mMovieData.get(position);
//Set the textView holder
viewHolder.movieTextView.setText(movieItem.getTitle());
//use picasso to load images to the holder
Picasso.with(mContext).load(BASE_IMAGE_URL + movieItem.getPoster_path()).fit().into(viewHolder.moviePoster);
return cv;
}
static class ViewHolder{
TextView movieTextView;
ImageView moviePoster;
}
}
입니다
package com.xxcanizeusxx.erick.moviesnow;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new MovieFragment())
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
//Inflate the menu, this adds items to actionbar if present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if (id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
}
내 girdLayout의 XML
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/grid_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/gridView"
android:numColumns="2"
android:gravity="center"
android:drawSelectorOnTop="true"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp">
</GridView>
</FrameLayout>
내 movieItem XML을합니다 (GridLayout과를 채우려면)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/movie_detail_item"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/movie_poster"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/movie_title"
android:maxLines="2"
android:gravity="center"
android:textSize="14sp"
android:textAllCaps="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
화살표를 사용하여 좋은 설명 – avinash
답장을 보내 주셔서 감사합니다.이 주제는 여전히 혼란 스럽지만 앞으로 의문점을 해결해 주셨습니다. 나는 정말로 그 반응에 감사한다. –
어느 부분에 혼란스러워하십니까? 나는 당신의 방법의 반환 유형을 고쳤다. 다른 파트를 변경하여 원하는 유형의 실제 결과를 얻을 수도 있습니다. –