Computer >> Hướng Dẫn Máy Tính >  >> Xử Lý Sự Cố >> Android

Cách thêm API Fetcher vào ứng dụng Android của bạn

Nếu bạn là nhà phát triển ứng dụng, có lúc bạn muốn tích hợp API web để lấy dữ liệu cho người dùng. Không quá khó, có thể làm bằng XML hoặc JSON. Trong hướng dẫn này, chúng tôi sẽ chỉ cách xây dựng một trình lấy dữ liệu API web đơn giản vào ứng dụng Android.

Hướng dẫn này sử dụng JSON thay vì XML.

Viết mã bằng JSON

Đầu tiên tạo file XML List View mới với mã sau:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@+id/list_title_list" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout> Tiếp theo tạo file XML mới, nơi liệt kê các phần tử muốn hiển thị (ImageView, TextView, v.v.) <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="80dp" android:orientation="vertical" android:padding="5dp" > <ImageView android:id="@+id/iv_icon_social" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerVertical="true" android:visibility="gone" /> <LinearLayout android:id="@+id/thumbnail" android:layout_width="fill_parent" android:layout_height="85dp" android:layout_marginRight="50dp" android:layout_marginTop="0dp" android:layout_toRightOf="@+id/iv_icon_social" android:gravity="center_vertical" android:orientation="vertical" android:padding="5dip" android:visibility="visible" > <TextView android:id="@+id/txt_ttlsm_row" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:text="Sample text" android:textSize="18dp" android:textStyle="bold" /> <TextView android:id="@+id/txt_ttlcontact_row2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="0dp" android:layout_marginTop="3dp" android:paddingLeft="10dp" android:maxEms="20" android:maxLines="2" android:singleLine="false" android:ellipsize="end" android:text="Sample text2" android:textColor="#808080" android:textSize="15dp" android:textStyle="normal" /> </LinearLayout> </RelativeLayout>

Để lấy dữ liệu từ API, cần vào Main Activity và dùng AsyncTask vì lấy API không thể trên main thread. AsyncTask là luồng xử lý nền, hiển thị kết quả trên UI. Dùng main thread cho mạng thường làm crash app. Nếu hơi khó hiểu, xem các hướng dẫn API sâu hơn trên RapidAPI.

class DownloadFilesTask extends AsyncTask < Void, Void, String > { private final ProgressDialog dialog = new ProgressDialog(MainActivity.this); @Override protected void onPreExecute() { super.onPreExecute(); this.dialog.setMessage("Signing in..."); this.dialog.show(); } @Override protected String doInBackground(Void...params) { ServiceHandler sh = new ServiceHandler(); String jsonStr = sh.makeServiceCall("https://jsonplaceholder.typicode.com/albums/", ServiceHandler.GET); Log.d("res1", jsonStr); return jsonStr; } @Override protected void onPostExecute(String response) { super.onPostExecute(response); Log.d("res2", response); dialog.dismiss(); if (response != null) { try { JSONArray arr = new JSONArray(response); DataModel mDatModel = new DataModel(); for (int i = 0; i < arr.length(); i++) { JSONObject c = arr.getJSONObject(i); String id=c.getString(ID); String title = c.getString(TITLE); String uid = c.getString(USER_ID); id_array.add(id); // Toast.makeText(getApplicationContext(), title, Toast.LENGTH_LONG).show(); } adapter = new AAdapter(MainActivity.this, id_array); l.setAdapter(adapter); } catch (Exception e) {} } } } MainActivity.java public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { AAdapter adapter; ArrayList < String > id_array = new ArrayList < String > (); ArrayList < String > notice_array = new ArrayList < String > (); Button b1; ListView l; private final static String SERVICE_URI = "https://jsonplaceholder.typicode.com/albums/"; private static final String TAG_QUESTIONS = "Questions"; private static final String USER_ID = "userId"; private static final String ID = "id"; private static final String TITLE = "title"; JSONArray questions = null; protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); l = (ListView) findViewById(R.id.list); new DownloadFilesTask().execute(); l.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView < ? > parent, View view, int position, long id) { String abc = id_array.get(position); Toast.makeText(getBaseContext(), id_array.get(position), Toast.LENGTH_LONG).show(); Intent n = new Intent(MainActivity.this, Titleshow.class); n.putExtra("id", id_array.get(position)); startActivity(n); } }); } @Override public void onItemClick(AdapterView < ? > parent, View view, int position, long id) {}

Bạn sẽ tìm thấy phản hồi trong main activity

ServiceHandler sh = new ServiceHandler(); String jsonStr = sh.makeServiceCall("https://jsonplaceholder.typicode.com/albums/", ServiceHandler.GET); this nothing but a service handle class to request and get the respose from web api so we will do all this from web api. ServiceHandler.java class ServiceHandler { static String response = null; public final static int GET = 1; public final static int POST = 2; public ServiceHandler() {} /** * Making service call * * @url - url to make request * @method - http request method */ public String makeServiceCall(String url, int method) { return this.makeServiceCall(url, method, null); } /** * Making service call * * @url - url to make request * @method - http request method * @params - http request params */ public String makeServiceCall(String url, int method, List < NameValuePair > params) { try { // http client DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; // Checking http request method type if (method == POST) { HttpPost httpPost = new HttpPost(url); // adding post params if (params != null) { httpPost.setEntity(new UrlEncodedFormEntity(params)); } httpResponse = httpClient.execute(httpPost); } else if (method == GET) { // appending params to url if (params != null) { String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; } HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } httpEntity = httpResponse.getEntity(); response = EntityUtils.toString(httpEntity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return response; } }

Tiếp theo trong asyncTask, bạn sẽ thấy lớp Adapter, sẽ thiết lập phương thức adapter, nhưng cần tạo custom adapter.

public class AAdapter extends BaseAdapter { private Activity activity; // private ArrayList<HashMap<String, String>> data; private static ArrayList title; private static LayoutInflater inflater = null; public AAdapter(Activity a, ArrayList b) { activity = a; this.title = b; inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public int getCount() { return title.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { View vi = convertView; if (convertView == null) vi = inflater.inflate(R.layout.abcd, null); TextView title2 = (TextView) vi.findViewById(R.id.txt_ttlsm_row); // title String song = title.get(position).toString(); title2.setText(song); TextView title22 = (TextView) vi.findViewById(R.id.txt_ttlcontact_row2); // notice String song2 = title.get(position).toString(); title22.setText(song2); return vi; } }

Cần nhớ lớp adapter được coi là lớp trừu tượng trong Android, nên phải triển khai tất cả phương thức. Trong mã dưới, phương thức getview quan trọng, vì sẽ thêm mã để hiển thị file XML thứ hai.

inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Cũng cần lớp Adapter cho Load Image, để API fetcher tải ảnh từ internet.

public class MyAdapter extends BaseAdapter { ImageLoader imageLoader; private Context ctx; ArrayList < AlbumData > list; public MyAdapter(Context ctx, ArrayList < AlbumData > mDataList) { list = mDataList; this.ctx = ctx; } public int getCount() { return list.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { // View vi = convertView; ViewHolder viewHolder; if (convertView == null) { LayoutInflater vi = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.abcde, null); viewHolder = new ViewHolder(); viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image); viewHolder.textView = (TextView) convertView.findViewById(R.id.txt_ttlsm_row); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } AlbumData data = list.get(position); String a = data.getThumbnailUrl(); if (data != null) { viewHolder.textView.setText(data.getTitle()); String url = a; Glide.with(ctx).load(url).centerCrop().placeholder(R.drawable.abhi).crossFade().into(viewHolder.imageView); /* Picasso.with(ctx) .load("https://preview.keenthemes.com/conquer/assets/plugins/jcrop/demos/demo_files/image2.jpg") .into(viewHolder.imageView);*/ /* ImageLoader imageLoader = ImageLoader.getInstance(); imageLoader.displayImage("https://www.keenthemes.com/preview/conquer/assets/plugins/jcrop/demos/demo_files/image1.jpg", viewHolder.imageView);*/ } return convertView; } public class ViewHolder { ImageView imageView; TextView textView; }

Chúng tôi thêm chú thích mã chỉ là gợi ý cho Picasso image loader, thư viện tải và cache ảnh mã nguồn mở mạnh mẽ cho Android, chiếm dung lượng nhẹ. Tuy nhiên, cũng có thể dùng Glide image loader để tùy chỉnh hơn, vì hỗ trợ GIF và quản lý bộ nhớ tốt hơn.

public class ViewHolder { ImageView imageView; TextView textView; }

Lớp ViewHolder tạo instance tĩnh của ViewHolder, gắn vào view item khi tải lần đầu. Sau đó sẽ lấy từ tag view trong các lần gọi sau.

Phương thức getView() được gọi nhiều lần khi ListView có nhiều phần tử. Triển khai lớp data model cho set/get giúp lấy phần tử array list dễ dàng hơn sau này.

public class AlbumData { int albumId; int id; String title; String url; String thumbnailUrl; public int getAlbumId() { return albumId; } public void setAlbumId(int albumId) { this.albumId = albumId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getThumbnailUrl() { return thumbnailUrl; } public void setThumbnailUrl(String thumbnailUrl) { this.thumbnailUrl = thumbnailUrl; } }

Đó là tất cả những gì bạn cần. Có thể test API fetcher này trên trình giả lập app như BlueStacks.