- Android Architecture
- Intent
- Activity
- Activity간 연동
- Service
- AIDL
- BroadcastReceiver
- ContentProvider 생성
- Android UI
- Android Thread
- Thread with Post
- Thread with runOnUiThread
- Thread with Handler 1
- Thread with Handler 2
- Thread with AsyncTask
- AndroidManifest.xml
- PreferenceScreen
- ADB
- 참고 문헌
- 탐색
스마트폰인 Android의 SDK를 정리 한다.
Android Architecture
http://developer.android.com/images/system-architecture.jpg
Intent
Activity
Android Activity의 정의
Application에서 각 화면의 처리를 담당하는 모듈로 일반적으로 Intent를 통한 요청으로 실행됨
Activity의 크기는 기본적으로 Status Bar 영역을 제외한 화면 전체임
Activity의 이름은 "a
z 09 _ ." 문자만 사용할 수 있음
public class android.app.Activity extends ContextThemeWrapper
implements android.view.LayoutInflater.Factory,
android.view.Window.Callback,
android.view.KeyEvent.Callback,
android.view.View.OnCreateContextMenuListener,
ComponentCallbacks
Activity Lifecycle
http://developer.android.com/images/activity_lifecycle.png
{|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" |- |width="20%" align="center" style="background-color:#eee;"|onCreate(~) |width="80%"| - protected void onCreate(Bundle savedInstanceState) - startActivity(Intent intent)) 함수에 의해서 실행이 된다. - 저장된 상태값을 사용하여 Activity의 초기화를 한다. |- |align="center" style="background-color:#eee;"|onStart() | - protected void onStart() - onStart() 함수가 호출되면 Activity가 Background(화면에 보이지 않음)에서 실행 대기 한다. |- |align="center" style="background-color:#eee;"|onRestart() | - protected void onRestart() |- |align="center" style="background-color:#eee;"|onResume() | - protected void onResume() - Activity가 Foreground(화면에 보임)에서 사용자의 입력을 처리하여야 할 때 호출 된다. - onResume()가 호출되면 해당 Activity가 제어권을 가진다. |- |align="center" style="background-color:#eee;"|onPause() | - protected void onPause() - Activity가 Background(화면에 보이지 않음)에서 실행되어야 할 때 호출 된다. - onPause()가 호출되면 해당 Activity가 제어권을 잃는다. - Activity의 상태값을 저장 한다. |- |align="center" style="background-color:#eee;"|onStop() | - protected void onStop() |- |align="center" style="background-color:#eee;"|onDestroy() | - protected void onDestroy() - Finish() 함수를 통해 언제든지 Activity를 종료할 수 있다. |- |align="center" style="background-color:#eee;"|onActivityResult(~) | - protected void onActivityResult(int requestCode, int resultCode, Intent data) - requestCode : startActivityForResult(~) 함수가 호출될 때 두번째 인자로 전달한 요청 코드 - 호출 받은 Activity에서 setResult(resultCode, data) 또는 setResult(resultCode)를 설정하여야 한다. - startActivityForResult(Intent, requestCode) 함수를 사용하여 Activity가 호출 하였을 경우, 해당 Activity가 종료되면 OnActivityResult(~) 함수가 호출 된다. |}
Activity 내역 보기
cd c:/appl/androidSDK/tools/
adb shell dumpsys activity
화면 회전 금지
참조 : 화면 전환 호출과 데이터 복구
AndroidManifest.xml에서 모든 Activity에 다음을 추가 한다.
android:screenOrientation="portrait"
Activity간 연동
하나의 Activity에서 다른 Activity를 호출할 때, Intent를 사용하여 값을 전달할 수 있다. 마찬가지로 호출된 Activity는 Intent를 사용하여 값을 반환할 수 있다. 여기서는 startActivityForResult를 사용하여 두 Activity간 연동하는 방법을 살펴 보자.
호출하는 Activity를 A Activity라고 하고 호출받는 Activity를 B Activity라고 해보자.
A Activity에서 B Activity 호출
A Activity 구현
startActivityForResult(Intent intent, int requestCode) : requestCode로 어떤 activity에서 호출했는지 확인 가능
Intent intent = new Intent(getApplicationContext(), SettingActivity.class);
intent.putExtra("data", "전달하는 값"); //--- 전달할 값 저장
startActivityForResult(intent, 1);
B Activity 구현
String data = getIntent().getStringExtra("data"); //--- 전달받은 값
B Activity에서 A Activity로 반환
B Activity 구현
setResult(resultCode) 또는 setResult(resultCode, Intent data)으로 결과 반환
resultCode : Activity.RESULT_OK, Activity.RESULT_CANCELED 등
주의 : "이전 메뉴" 메뉴를 선택하면 Activity.RESULT_CANCELED 가 반환 된다.
일반적으로 protected void onPause() 에서 구현 한다.
Intent result = new Intent();
result.putExtra("result", "반환하는 값"); //--- 반환하는 값 저장
setResult(Activity.RESULT_CANCELED, result);
A Activity 구현
//--- 호출 받은 앱에서 결과값을 반환했을 때, 처리하는 함수
//--- 주의 : "이전 메뉴" 메뉴를 선택하면 Activity.RESULT_CANCELED 가 반환 된다.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
String result = null;
super.onActivityResult(requestCode, resultCode, data);
switch (resultCode) {
case Activity.RESULT_OK:
break;
case Activity.RESULT_CANCELED:
if (requestCode == 1) { //--- requestCode로 어떤 Activity에서 반환되었는지 확인 한다.
if (data != null) {
result = data.getStringExtra("result"); //--- 반환된 값
if ((result != null) && (result.equals("error"))) {
finish();
}
}
}
break;
}
}
Service
public abstract class android.app.Service extends ContextWrapper implements ComponentCallbacks
정의
서비스는 백그라운드 작업을 처리 하거나 IPC (Inter-Process Communication)을 위한 원격 접속이 가능한 오브젝트를 만든다.Intent 받아 백그라운드 작업을 처리하는 객체
Intent를 받아 IPC (Inter-Process Communication)을 위한 원격 접속 처리를 하는 객체
http://developer.android.com/images/service_lifecycle.png
백그라운드 Service
public void onCreate()
public void onStart(Intent intent, int startId)
private java.util.TimerTask task = new TimerTask() {
public void run() {
}
}
private java.util.Timer timer = new Timer();
timer.schedule(task, 5000);
public void onDestroy()
IPC용 Service
private final ISimpleMathService.Stub binder = new ISimpleMathService.Stub() { 구현 }
public void onCreate()
public abstract IBinder onBind(Intent intent)
return this.binder;
public void onRebind(Intent intent)
public boolean onUnbind(Intent intent)
public void onDestroy()
Publishing
Local
public class ActivityExample extends Activity {
private ISimpleMathService service;
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder iservice) {
service = ISimpleMathService.Stub.'''asInterface(iservice)''';
}
public void onServiceDisconnected(ComponentName className) {
service = null;
}
}
public void onStart() {
this.bindService(
new Intent(ActivityExample.this, SimpleMathService.class),
connection,
Context.BIND_AUTO_CREATE);
}
public void onPause() {
this.unbindService(connection);
}
}
Remote Service
public class SimpleMathService extends Service {
private final ISimpleMathService.Stub binder = new ISimpleMathService.Stub() { 구현 }
public abstract IBinder onBind(Intent intent) {
return this.binder;
}
}
AIDL
Android Interface Definition Language
원격 접속이 가능한 객체를 만들때 사용
AIDL을 사용한 IPC 구현
AIDL 원격 인터페이스 정의 파일 (~.aidl)
package com.msi.manning.binder;
interface ISimpleMathService {
int add([](in)int a, out int b, inout int c)
}
in(디폴트), out, inout
AIDL에서 지원하는 type
{|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center"
|-
|width="20%" align="center" style="background-color:#eee;"|Type
|width="60%" align="center" style="background-color:#eee;"|설 명 |width="20%" align="center" style="background-color:#eee;"|Import 여부 |- |Java primitives |boolean, byte, short, int, float, double, long, char |align="center"|필요 없음 |- |String |java.lang.String |align="center"|필요 없음 |- |CharSequence |java.lang.CharSequence |align="center"|필요 없음 |- |List |ArrayList |align="center"|필요 없음 |- |Map |HashMap |align="center"|필요 없음 |- |Other AIDL interface |기타 AIDL 인터페리스 타입으로 만들어진 것 |align="center"|필요 |- |Parcelable object |Android Parcelable interface를 구현한 것 |align="center"|필요 |}$ANDROID_HOME/tools/aidl
ISimpleMathService
ISimpleMathService.Stub : Local
ISimpleMathService asInterface(IBinder b)
ISimpleMathService.Stub.Proxy : Remote
BroadcastReceiver
public abstract class android.content.BroadcastReceiver
정의
Activity도 Service도 아니지만 Intent를 받아 간단한 작업을 처리 한다.BroadcastReceiver 호출
android.content.Context.sendBroadcast(Intent intent)
android.content.Context.sendStickyBroadcast(Intent intent)
android.content.Context.sendOrderedBroadcast(Intent intent, String receiverPermission)
BroadcastReceiver의 Intent 처리 함수
android.content.BroadcastReceiver.onReceive(Context context, Intent intent)
Broadcast 중단 : this.abortBroadcast();
ContentProvider 생성
public abstract class android.content.ContentProvider implements ComponentCallbacks
public class MyProvider extends ContentProvider {
public boolean onCreate() {
}
private static UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
URI_MATCHER.addURI(authority, "widgets", 2);
URI_MATCHER.addURI(authority, "widgets/#", 1);
//--- Uri로 MIME TYPE를 반환 한다.
public String getType(Uri uri) {
switch (MyProvider.URI_MATCHER.match(uri)) {
case 2 : return "vnd.android.cursor.dir/vnd.msi.mywidget";
case 1 : return "vnd.android.cursor.item/vnd.msi.mywidget";
default : throw new IllegalArgumentException("Unknown URI " + uri);
}
}
public Uri insert(Uri uri, ContentValues contentvalues) {
public static Uri CONTENT_URI = Uri.parse("content://authority/widgets");
//--- 등록된 레코드의 ID (rowId)로 URI를 생성하여 notify 한다.
Uri result = ContentUris.withAppendedId(CONTENT_URI, rowId);
this.getContext().getContentResolver().notifyChange(result, null);
return result; //--- 등록된 레코드의 URI
}
public int update(Uri uri, ContentValues contentvalues, String s, String as[](.md)) {
//--- 수정된 URI를 notify 한다.
this.getContext().getContentResolver().notifyChange(uri, null);
return 수정된 갯수;
}
public int delete(Uri uri, String s, String as[](.md)) {
//--- 삭제된 URI를 notify 한다.
this.getContext().getContentResolver().notifyChange(uri, null);
return 삭제된 갯수;
}
public Cursor query(Uri uri, String as[], String s, String as1[](.md), String s1) {
Cursor cur <- SQLiteQueryBuilder()
//--- 향후의 notify를 위해 조회한 URI를 Cursor에 저장하여 반환 한다.
cur.setNotificationUri(this.getContext().getContentResolver(), uri);
return cur;
}
}
AndroidManifest.xml
Android UI
Android Thread
Android는 Java로 되어 있어 Java에서 제공하는 기능을 사용하여 Thread를 구현할 수 있습니다. 그러나, 안드로이드 화면의 각 요소(View)에 정보를 표시한다든지 하는 UI와 관련된 작업을 하는 경우에는 여러가지 제약 사항이 따릅니다.
Thread에서 UI 처리를 하기 위해서는 반드시 Activity 내에서 구현이 되어야 합니다.Thread with Post
view.post()를 사용하여 UI 처리
new Thread(new Runnable() {
public void run() {
view.post(new Runnable() {
public void run() {
view.setText("hello");
}
});
}
}).start();
Thread with runOnUiThread
Activity의 runOnUiThread()를 사용하여 UI 처리
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
view.setText("hello");
}
});
}
}).start();
Thread with Handler 1
Handler를 사용하여 UI 처리
private Handler handler = new Handler();
new Thread(new Runnable() {
public void run() {
handler.post(new Runnable() {
public void run() {
view.setText("hello");
}
});
}
}).start();
Thread with Handler 2
android.os.Message
sendEmptyMessage(int what)
sendEmptyMessageAtTime(int what, long time)
sendEmptyMessageDelayed(int what, long delay)
Runnable
postEmptyMessage()
android.os.Looper
ANR (Application Not Responding, 응답없는 애플리케이션)
5초 동안 사용자의 입력에 대해서 반응을 보이지 않는 애플리케이션
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
private Handler handler = new Handler() {
public void handleMessage(final Message msg) {
view.setText(msg.getData().getString("rtcd"));
}
};
new Thread() {
public void run() {
Bundle bundle = new Bundle();
bundle.putString("rtcd", "OK");
Message msg = handler.obtainMessage();
msg.setData(bundle);
handler.sendMessage(msg);
//handler.handleMessage(msg);
}
}.start();
Thread with AsyncTask
Google에서는 AsyncTask라는 것을 제공하여 Android에서 UI 작업과 관련된 Thread의 구현을 손쉽게 할 수 있도록 지원 합니다.
UI Thread를 구현하기 위해서는 해당 Thread가 Activity에서 구현이 되어야 하며, 주고 받는 인자들의 타입이 일치 하여야 합니다. 아래 설명에서는 서로 일치해야 하는 인자들의 경우에는 동일한 색으로 표시를 해서 구분 합니다.
AsyncTask 호출 구현
private Activity activity = null;
activity = this;
(new theAsyncThread()).execute(para1, para2, para3);
AsyncTask 구현
private class theAsyncThread extends AsyncTask<String, String, String> {
//--- Thread를 시작하기 전에 호출되는 함수
protected void onPreExecute() {
if ((activity != null) && (activity.isFinishing() == false)) {
Toast.makeText(activity, "Before thread", Toast.LENGTH_SHORT).show();
}
super.onPreExecute();
}
//--- Thread의 주요 작업을 처리 하는 함수
//--- Thread를 실행하기 위해 excute(~)에서 전달한 값을 인자로 받습니다.
protected String doInBackground(String... arg) {
int argCnt = 0;
argCnt = arg.length;
if (argCnt != 3) {
return "Error";
}
//--- onProgressUpdate(~) 실행하기 위해서는 아래 함수를 호출 합니다.
publishProgress("Thread processing.");
return "OK";
}
//--- doInBackground(~)에서 호출되어 주로 UI 관련 작업을 하는 함수
protected void onProgressUpdate(String... progress) {
if ((activity != null) && (activity.isFinishing() == false)) {
Toast.makeText(activity, progress[0](0.md), Toast.LENGTH_SHORT).show();
}
}
//--- Thread를 처리한 후에 호출되는 함수
//--- doInBackground(~)의 리턴값을 인자로 받습니다.
protected void onPostExecute(String result) {
if ((activity != null) && (activity.isFinishing() == false)) {
Toast.makeText(activity, "After thread", Toast.LENGTH_SHORT).show();
}
super.onPostExecute(result);
}
//--- AsyncTask.cancel(true) 호출시 실행되어 thread를 취소 합니다.
protected void onCancelled() {
super.onCancelled();
}
}
참고 문헌
AndroidManifest.xml
Root 폴더에 존재하며 애플리케이션의 환경, Activity, Service, BroadcastReceiver, ContentProvider, Permission 등을 정의
,
- , , ,
PreferenceScreen
Preference 종류
CheckBoxPreference
EditTextPreference
DialogPreference
ListPreference
RingtonePreference
res/xml/settings.xml
/data/data/패키지/shared_prefs/패키지_preferences.xml 로 저장됨
Activity
public class Settings extends PreferenceActivity {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
private ListPreference pref = null;
pref = (ListPreference) findPreference("maxContacts");
pref.setSummary(pref.getValue());
pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
app.setMaxContacts(Integer.parseInt((String)newValue));
pref.setSummary((String)newValue);
return true;
}
});
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
return false;
}
});
PreferenceScreen screen = (PreferenceScreen)getPreference("root_key");
CheckBoxPreference cb = (CheckBoxPreference)getPreference("key2");
screen.setEnabled(true);
Parent.setSummary("string depending on the selection");
ADB
참고 문헌
탐색
{|cellspacing="0" cellpadding="2" border=01" width="100%" bgcolor="#FFFFFF" align="center"
|-
|width="30%" align="center"|Android
|width="40%" align="center"|Android SDK
|width="30%" align="center"|Android Market
|}
분류: Android
오픈소스
Google
Mobile