저는 Android 세계에서 매우 새로 왔습니다. 아름다운 Rest API를 개발 한 후에 안드로이드 개발이 쉬울 것이라고 생각했지만 기본에 매달렸다.Android 활동에서 API 및 DB 호출을 추출하는 방법은 무엇입니까?
내 Android 앱에서 올바른 자격 증명이 제공되면 토큰을 반환하는 API 호출을 만드는 로그인을 만들었습니다. 이 토큰은 공유 환경 설정에 저장되며 사용자는 주요 활동 : HomeActivity로 리디렉션됩니다. 그것의 버튼을 사용자가 클릭이 새로운 조각을로드 할 수 있도록하는 경우,
그것은 BottomNavigationBar 있습니다
이 활동은 할 일이 많이있다.
리소스를 얻고 프래그먼트에 따라 표시하려면 API 끝점을 호출하십시오.
과부하 서버를 피하기 위해 데이터베이스에 API 응답을 저장하십시오.
확실히, 안드로이드 개발자를위한이 매우 쉬운 것입니다,하지만 내이 같다 : 방법 나는 API 호출을 만들고있어 loadContents()
에 빠른 요약은
import android.arch.persistence.room.Room;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.ibosca.thub.database.AppDatabase;
import com.ibosca.thub.helpers.BottomNavigationViewHelper;
import com.ibosca.thub.models.Channel;
import com.ibosca.thub.models.Content;
import com.ibosca.thub.models.ContentList;
import com.ibosca.thub.models.Town;
import com.ibosca.thub.models.User;
import com.ibosca.thub.parser.ContentParser;
import com.ibosca.thub.volley.MySingleton;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HomeActivity extends AppCompatActivity {
private String userToken;
public TextView contentList;
private ContentParser contentParser = new ContentParser();
public static AppDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "townhub").build();
contentList = (TextView) findViewById(R.id.contentList);
loadContents();
SharedPreferences sharedPref = getSharedPreferences(MainActivity.PACKAGE_NAME, Context.MODE_PRIVATE);
userToken = sharedPref.getString("token", null);
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
View contentsButton = bottomNavigationView.findViewById(R.id.action_contents);
contentsButton.performClick();
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Toast toast = Toast.makeText(getApplicationContext(), "UNDF", Toast.LENGTH_LONG);
switch (item.getItemId()) {
case R.id.action_towns:
toast = Toast.makeText(getApplicationContext(), "Towns", Toast.LENGTH_LONG);
break;
case R.id.action_channels:
toast = Toast.makeText(getApplicationContext(), "Channels", Toast.LENGTH_LONG);
break;
case R.id.action_contents:
loadContents();
break;
case R.id.action_question:
toast = Toast.makeText(getApplicationContext(), "Questions", Toast.LENGTH_LONG);
break;
case R.id.action_user:
toast = Toast.makeText(getApplicationContext(), "Settings", Toast.LENGTH_LONG);
break;
}
toast.show();
return true;
}
});
}
public void ExecuteInsert(ContentList...lists){
new InsertContents().execute(lists);
}
protected void loadContents() {
String url = MySingleton.BASE_URL + "/contents";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
ContentList list = contentParser.fromContents(response);
ContentList[] lists = new ContentList[1];
lists[0] = list;
ExecuteInsert(lists);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Failed to connect", Toast.LENGTH_LONG).show();
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + userToken);
return headers;
}
};
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
}
public static class InsertContents extends AsyncTask<ContentList, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
//Perform pre-adding operation here.
}
@Override
protected Void doInBackground(ContentList...lists) {
ContentList list = lists[0];
//Insert towns, channels
db.townDao().insertArrayList(list.getTowns());
db.channelDao().insertArrayList(list.getChannels());
db.userDao().insertArrayList(list.getUsers());
db.contentDao().insertArrayList(list.getContents());
//Select data from DB
List<Town> towns = db.townDao().getAll();
List<Channel> channels = db.channelDao().getAll();
List<User> users = db.userDao().getAll();
List<Content> contents = db.contentDao().getAll();
for (int i = 0; i < contents.size(); i++) {
Content content = contents.get(i);
Town contentTown = db.townDao().findById(content.getTownId());
Log.i("Poble: ", contentTown.getName());
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//To after addition operation here.
}
}
}
; 클래스 InsertContents
은 로컬 데이터베이스에서 재생할 수있는 곳입니다. 마지막으로
, 질문 :
1) 당신이 볼 수 있듯이, 내가 API 호출을 위해 발리를 사용하고 있습니다. 분리 된 클래스에 "api 끝점"을 넣고 Activity에서이 클래스를 사용하는 것이 가장 좋습니다. Android 개발시이 코드를 분리하는 방법은 무엇입니까?
2) 데이터베이스 관리와 동일합니다. 어떻게 분리 된 클래스에 코드를 넣고 Activity에서 호출 할 수 있습니까? 이 작업은 현재 완료되었지만 AsyncTask에서 TextView를 업데이트 할 수 없습니다. TextView를 업데이트하면 ListView 또는 ReciclerView를 사용하는 것이 최종 목표입니다.
개선을위한 제안 사항은 무엇입니까? 환영합니다.
https://github.com/googlesamples/android-architecture – LordRaydenMK
개선판을 보시기 바랍니다. 이것은 REST API를 Java API로 변환 할 수있는 라이브러리입니다. –