와챠의 우당탕탕 개발 기록장
[안드로이드]MariaDB <=> Apache <=> Android (PHP + Json)(2) 본문
[안드로이드]MariaDB <=> Apache <=> Android (PHP + Json)(2)
minWachya 2021. 4. 30. 10:28이전 글에서는 DB를 만들고 웹에서 DB의 내용을 받아 Json 형태의 배열로 만들어주는 부분까지 했었다.
이 글에서는 안드로이드에 이 Json 배열을 어떻게 받아서 처리하는지 알아보겠다.
만들어볼 앱은 아래와 같다.

버튼을 누르면

이렇게 뜨는 앱을 만들어 볼 것이다.
build.gradle(:app)에 추가할 것들
1, plugins에 id 'kotlin-android-extensions' 추가

변수 선언/xml파일과의 연결 작업 도와주는 플러그인이다.
추가 후 MainActivity.kt에 import kotlinx.android.synthetic.main.activity_main.* 해줘야 함!
2, dependencies에 통신 간결하게 해주는 implementation 'com.squareup.okhttp3:okhttp:3.8.1' 추가
3, dependencies에 implementation 'com.google.code.gson:gson:2.8.5' 추가
Json파일에 있는 데이터를 자바/코틑린 클래스의 Object로 쉽게 전환해준다.

Sync Now해주면 build.gradle(:app) 작업은 끝!
AndroidManifest.xml에 추가할 것들
1, Json 파일을 안드로이드로 가지고 오기 위해 웹서버 접근 허용하기위해서
<uses-permission android:name="android.permission.INTERNET" />해주기
2, http 사이트에 대한 접근 허용 위해 application에 android:usesCleartextTraffic="true" 해주기
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.example.myphpjson"> | |
<uses-permission android:name="android.permission.INTERNET" /> | |
<application | |
android:allowBackup="true" | |
android:icon="@mipmap/ic_launcher" | |
android:label="@string/app_name" | |
android:roundIcon="@mipmap/ic_launcher_round" | |
android:usesCleartextTraffic="true" | |
android:supportsRtl="true" | |
android:theme="@style/Theme.MyPhpJson"> | |
<activity android:name=".MainActivity"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> | |
</application> | |
</manifest> |
끝!
이제 어느 파일들이 필요한지 알아본 뒤 자세한 코드들을 알아보자.
activity_main.xml : 리사이클러뷰

hinfo.xml : 리사이클러뷰에 들어갈 아이템

hinfo.kt : 리사이클러뷰에 들어갈 데이터 클래스, 인자는 Json 피일에서 불러올 데이터 형식과 같음
JsonObj.kt : hinfo에 대한 배열을 갖는 데이터 클래스
hinfoAdapter.kt : 리사이클러뷰의 어댑터 클래스(리사이클러뷰는 어댑터가 필요함)
MainActivity.kt : 버튼 누르면 서버에서 정보 받아와 화면에 보여주는 동작 처리
<xml 코드>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".MainActivity" | |
android:orientation="vertical"> | |
<Button | |
android:id="@+id/btn1" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="데이터 불러오기"/> | |
<androidx.recyclerview.widget.RecyclerView | |
android:id="@+id/recyclerView" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"/> | |
</LinearLayout> |
hinfo.xml
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<androidx.cardview.widget.CardView | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="horizontal"> | |
<TextView | |
android:id="@+id/tvName" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="이름" | |
android:textSize="20dp" | |
android:layout_weight="1"/> | |
<TextView | |
android:id="@+id/tvAge" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="나이" | |
android:textSize="20dp" | |
android:textColor="#00ffff" | |
android:layout_weight="1"/> | |
<TextView | |
android:id="@+id/tvAddress" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="주소" | |
android:textSize="20dp" | |
android:textColor="#ff00ff" | |
android:layout_weight="1"/> | |
</LinearLayout> | |
</androidx.cardview.widget.CardView> | |
</LinearLayout> |
<kt 코드>
hinfo.kt
package com.example.myphpjson | |
// 리사이클러뷰에 들어갈 데이터 클래스 | |
// 인자는 Json 피일에서 불러올 데이터 형식과 같음 | |
data class hinfo (val Age:Int?, val name:String?, val address:String?) |
JsonObj.kt
package com.example.myphpjson | |
// hinfo에 대한 배열을 데이터로 갖는 데이터 클래스 | |
data class JsonObj (val result : ArrayList<hinfo>) |
hinfoAdapter.kt
package com.example.myphpjson | |
import android.text.Layout | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import androidx.recyclerview.widget.RecyclerView | |
import kotlinx.android.synthetic.main.hinfo.view.* | |
// 리사이클러뷰의 어댑터 클래스 | |
class hinfoAdapter(var items : JsonObj) : RecyclerView.Adapter<hinfoAdapter.ViewHolder>() { | |
// ViewHolder 만들기 | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
// 하나씩 띄어진 레이아웃 만들기, hinfo.xml연결 | |
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.hinfo, parent, false) | |
// 뷰홀더에 hinfo를 사용하는 view를 이용 | |
return ViewHolder(itemView) | |
} | |
// 아이템 갯수 리턴 | |
override fun getItemCount() = items.result.count() | |
// position 위치에 해당되는 hinfo정보값을 holder에 채우기 | |
override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
val item = items.result[position] | |
holder.setItem(item) | |
} | |
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) { | |
// hinfo 데이터 들어오면 hinfo.xml과 연결 | |
fun setItem(item : hinfo) { | |
itemView.tvName.text = item.name | |
itemView.tvAge.text = item.Age.toString() | |
itemView.tvAddress.text = item.address | |
} | |
} | |
} |
MainActivity.kt
package com.example.myphpjson | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.util.Log | |
import android.widget.Button | |
import android.widget.TextView | |
import androidx.recyclerview.widget.LinearLayoutManager | |
import androidx.recyclerview.widget.RecyclerView | |
import com.google.gson.GsonBuilder | |
import kotlinx.android.synthetic.main.* | |
import kotlinx.android.synthetic.main.activity_main.* | |
import okhttp3.* | |
import java.io.IOException | |
import java.net.URL | |
class MainActivity : AppCompatActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
// 버튼 누르면 Json 파일의 내용 불러와서 보여주기 | |
btn1.setOnClickListener { | |
// 리사이클러뷰의 매니저 설정 | |
recyclerView.layoutManager = LinearLayoutManager(this) | |
// 접근하려는 웹주소 "http://localhost/PHP_connection.php" | |
// localhost에는 ip주소로 | |
// cmd에 ipconfig 입력하면 IP주소 알 수 있음 | |
fetchJson("http://000.00.0.00/PHP_connection.php") | |
} | |
} | |
// url통해서 request하고 response받아서 | |
// response에서 전달받은 json에 대해서 jsonObj라는 데이터클래스로 바꾸고 | |
// 리사이클러로 보여주기 | |
fun fetchJson(myUrl : String) { | |
// 전달받은 string을 url로 만들기 | |
val url = URL(myUrl) | |
// request 만들기 | |
// 외부에 전달할 객체를 만들어주는 빌드 만들고, url 통해서 빌드 하기 | |
val request = Request.Builder().url(url).build() | |
// client통해서 request 전달하기 | |
val client = OkHttpClient() | |
// enqueue : request로부터 응답받은 response를 처리하는 작업이 들어감 | |
// Callback : response를 처리하는 클래스 | |
client.newCall(request).enqueue(object : Callback { | |
// 실패할 경우 오류 메시지 출력 | |
override fun onFailure(call: Call, e: IOException) { | |
Log.d("hinfo", "Failed to excute request!") | |
} | |
// 응답이 제대로 왔을 경우 | |
override fun onResponse(call: Call, response: Response) { | |
// response의 body로 내용 전달받음 | |
// {"result":[{"Age":"22","name":"Lee","address":"Seoul Korea"}, | |
// {"Age":"23","name":"Kim","address":"Suwon Korea"}~ 이 내용이 곧 body | |
val body = response?.body()?.string() | |
// 정달받은 body 확인해보기 | |
Log.d("hinfo", "Success to excute request! : $body") | |
// Json을 파싱해서 hinfo, jsonObj 형태로 변환하기 | |
// gson 생성 | |
val gson = GsonBuilder().create() | |
// fromJson : body라는 string을 JsonObj타입으로 변환해줌 | |
val list = gson.fromJson(body, JsonObj::class.java) | |
// 리스트를 리사이클러뷰에 보이기(스레드 이용) | |
runOnUiThread { | |
// 리사이클러뷰 어댑터 설정 | |
// (php에서 전달받은 json을 JsonObj로 변환시킨 list를 가지고 리사이클러뷰의 어댑터로 사용) | |
recyclerView.adapter = hinfoAdapter(list) | |
} | |
} | |
}) // 비동기적 처리 | |
} | |
} |
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[안드로이드]Python(Django) <=> MySQL <=> Json(1) (0) | 2021.05.01 |
---|---|
[안드로이드] 홍드로이드 #5 ListView 연습 (0) | 2021.05.01 |
[안드로이드]MariaDB <=> Apache <=> Android (PHP + Json)(1) (0) | 2021.04.29 |
[안드로이드] 10장 연습문제 5번(여러 액티비티 전환2) (0) | 2021.04.11 |
[안드로이드] 직접 풀어보기 10-1(여러 액티비티 전환) (0) | 2021.04.11 |