●어싱크태스트(Async Task)
- 네트워크 연결이므로, 연결시에 지연이 발생할 수 있다. 따라서 메인쓰레드(UI쓰레드)로 네트워크 접속을 시도하면 앱은 접속이 성공되고 응답을 받을때까지 동작을 못하게 된다. 따라서 안드로이드 최근버전부터는 메인쓰레드가 네트워크 접속을 시도하는것 자체를 금지한다.
- 웹서버로부터 데이터를 가져와서 ListView 등에 출력하려면 동생쓰레드에서 가져온 데이터를 UI에 반영하는 작업이 필요한데, 안드로이드에서는 개발자가 정의한 쓰레드는 UI를 제어할 수 없도록 금지시켜놓았다. 그래서 Handler를 사용해야 하는데 이 작업은 번거롭다.
그래서 AsyncTask라는 백그라운드 작업용 클래스를 지원하게 되었다.
- AsyncTask = Thread + Handler
●로딩중 표시(ProgressDialog)
- AsyncTask클래스 안에서 onPreExecute()안에 로딩중 표시 다이얼로그를 보여주고 onPostExecute()에 로딩중 표시 다이얼로그를 제거해준다.
●웹서버 연결 통신(HttpURLConnection)
- 접속대상 서버주소를 URL클래스와 통신을 담당하는 HttpURLConnection클래스를 이용해서 웹서버에 데이터를 넘겨주고 받는다.
- Manifest.xml에 '<uses-permission android:name="android.permission.INTERNET"/>, <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>'을 추가한다.
●예제
- WebConnectActivity.java
package com.example.day0425; import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; public class WebConnectActivity extends Activity implements OnClickListener{
Button btn; MyAsyncTask task; ListView listView; MyListAapter adapter;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webconnect);
listView = (ListView)findViewById(R.id.listView); adapter = new MyListAapter(this); listView.setAdapter(adapter);
btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(this);
} //웹에서 데이터를 가져오기 전에 먼저 네트워크 상태부터 확인 public void conntectCheck(){ ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { // fetch data //Toast.makeText(this,"네트워크 연결중입니다.", Toast.LENGTH_SHORT).show(); task = new MyAsyncTask(this); task.execute("");
} else { // display error Toast.makeText(this,"네트워크 상태를 확인하십시오", Toast.LENGTH_SHORT).show(); } }
public void onClick(View v) { conntectCheck(); } }
|
- webconnect.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="웹 연동 클릭" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp"/>
<ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView>
</LinearLayout>
|
- MyAsyncTask.java
package com.example.day0425; import java.util.ArrayList; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.widget.Toast; /* * Params - 비동기 작업시 필요한 데이터 자료형 * ex)웹사이트에 데이터 요청시 전송할 파라미터값(ID,PW 등....) * * Progress - 비동기 방식의 요청이 진행될때 사용될 데이터 자료형. * 숫자형 자료형을 많이 사용한다. * * Result - 웹서버로부터 가져오게 될 데이터에 알맞는 자료형을 개발자가 결정 * 주로 JSON, XML등을 가져오게 되므로 String을 많이 사용한다. */ public class MyAsyncTask extends AsyncTask<String, Integer, String>{
WebConnectActivity context; ProgressDialog dialog;
LoadManager load;//접속과 요청을 담당하는 객체 선언
public MyAsyncTask(Context context) { this.context = (WebConnectActivity)context;
load = new LoadManager();
}
//백그라운드 작업 수행전에 해야할 업무등을 이 메서드에 작성하며 되는데, //이 메서드는 UI쓰레드에 의해 작동하므로 UI를 제어할 수 있다. //따라서 이 타이밍에 진행바를 보여주는 작업등을 할 수 있다. protected void onPreExecute() { super.onPreExecute();
dialog = new ProgressDialog(context); //dialog.setCancelable(false); dialog.show(); }
//비동기방식으로 작동할 메서드이며, 주로 메인쓰레드와는 별도로 //웹사이트의 연동이나 지연이 발생하는 용도로 사용하면 된다. //사실상 개발자가 정의 쓰레드에서 run메서드와 비슷하다 // 'String...' 가변형 파라미터로 파라미터 개수 상관없이 넣을 수 있다. protected String doInBackground(String... params) {
//웹서버에 요청시도 String data = load.request();
return data; }
//백그라운드 메서드가 업무수행을 마칠때 호출되는 메서드. //UI쓰레드에 의해 호출되므로, UI쓰레드를 제어할 수 있다. //따라서 진행바를 그만 나오게 할 수 있다. protected void onPostExecute(String result) { super.onPostExecute(result);
dialog.dismiss(); Toast.makeText(context, result, Toast.LENGTH_SHORT).show(); System.out.println("a"); //최종적으로 웹서버로부터 데이터를 완전히 가져온 시점은 이 메서드이므로, //어댑터가 보유한 ArrayList를 갱신시켜주자! ArrayList<DataVo> dataList = context.adapter.lst; dataList.removeAll(dataList);
try { JSONObject o = new JSONObject(result); //JSONArray array = new JSONArray(result); JSONArray array = o.getJSONArray("a");
DataVo dataVo = null; JSONObject obj = null; System.out.println("1"); for(int i=0;i<array.length();i++){ obj = array.getJSONObject(i); dataVo = new DataVo(); System.out.println("2obj.getString(name):"+obj.getString("name")); dataVo.setName(obj.getString("name")); dataVo.setAge(obj.getInt("age")); dataVo.setIsBool(obj.getString("isBool"));
dataList.add(dataVo); context.listView.invalidateViews(); } System.out.println("3"); context.listView.invalidate();
System.out.println("array.length():"+array.length()); } catch (JSONException e) { e.printStackTrace(); }
}
} |
- LoadManager.java
package com.example.day0425; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class LoadManager { URL url; //접속대상 서버주소를 가진 객체 HttpURLConnection conn; //통신을 담당하는 객체 BufferedReader buffer=null; //필요한 객체 초기화 public LoadManager() { try { url = new URL("http://192.168.0.18:8080/index2.jsp"); conn = (HttpURLConnection)url.openConnection(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public String request(){ String data=""; try { conn.connect(); //웹서버에 요청하는 시점 InputStream is = conn.getInputStream(); //웹서버로부터 전송받을 데이터에 대한 스트림 얻기
//1byte기반의 바이트스트림이므로 한글이 깨진다. //따라서 버퍼처리된 문자기반의 스트림으로 업그레이드 해야 된다. buffer = new BufferedReader(new InputStreamReader(is));
//스트림을 얻어왔으므로, 문자열로 반환 StringBuffer str = new StringBuffer(); String d=null; while( (d=buffer.readLine()) != null){ str.append(d); }
data = str.toString();
} catch (IOException e) { e.printStackTrace(); } finally{ if(buffer!=null){ try { buffer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
return data;
}
}
|
- MyListAdapter.java
package com.example.day0425; import java.util.ArrayList; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class MyListAapter extends BaseAdapter{
ArrayList<DataVo> lst = new ArrayList<DataVo>(); Context context; LayoutInflater infalter;
public MyListAapter(Context context) { this.context = context; infalter = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() { return lst.size(); }
public Object getItem(int arg0) { return null; }
public long getItemId(int arg0) { return 0; }
public View getView(int position, View convertView, ViewGroup parent) { View view = null; if(convertView==null){ view = infalter.inflate(R.layout.list_item, parent, false); }else{ view = convertView; }
TextView txt_name = (TextView)view.findViewById(R.id.txt_name); TextView txt_age = (TextView)view.findViewById(R.id.txt_age); TextView txt_bool = (TextView)view.findViewById(R.id.txt_bool);
DataVo dataVo = (DataVo)lst.get(position);
txt_name.setText(dataVo.getName()); txt_age.setText(Integer.toString(dataVo.getAge())); txt_bool.setText(dataVo.getIsBool());
return view; }
}
|
- list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" >
<ImageView android:id="@+id/imgView" android:layout_width="0dp" android:layout_height="45dp" android:layout_weight="1" android:src="@drawable/ic_launcher"/> <TextView android:id="@+id/txt_name" android:layout_width="0dp" android:layout_height="45dp" android:layout_weight="1" android:text="이름" android:textSize="20dp" android:gravity="center"/> <TextView android:id="@+id/txt_age" android:layout_width="0dp" android:layout_height="45dp" android:layout_weight="1" android:text="22" android:textSize="20dp" android:gravity="center"/> <TextView android:id="@+id/txt_bool" android:layout_width="0dp" android:layout_height="45dp" android:layout_weight="1" android:text="true" android:textSize="20dp" android:gravity="center"/>
</LinearLayout> |
- DataVo.java
package com.example.day0425; public class DataVo { private String img; private String name; private int age; private String isBool;
public String getImg() { return img; } public void setImg(String img) { this.img = img; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getIsBool() { return isBool; } public void setIsBool(String isBool) { this.isBool = isBool; } }
|
- Manifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.day0425" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
<activity android:name="com.example.day0425.WebConnectActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
|
- http://192.168.0.18:8080/index2.jsp
{a:[{name:"토끼1",age:22,isBool:true},{name:"토끼2",age:25,isBool:true},{name:"토끼3",age:27,isBool:true}]} |
'프로그래밍 > 안드로이드' 카테고리의 다른 글
안드로이드 SharedPreferences (0) | 2015.05.10 |
---|---|
안드로이드 자바 소켓서버 통신 (0) | 2015.05.10 |
안드로이드 JSONObject, JSONArray (0) | 2015.04.26 |
안드로이드 ViewPager, SQLite 예제 소스 (0) | 2015.04.25 |
안드로이드 오픈소스 ViewPagerIndicator (0) | 2015.04.15 |
댓글