스마트폰인 Android의 SDK를 정리 한다.
http://developer.android.com/images/system-architecture.jpg
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
cd c:/appl/androidSDK/tools/
adb shell dumpsys activity
android:screenOrientation="portrait"
하나의 Activity에서 다른 Activity를 호출할 때, Intent를 사용하여 값을 전달할 수 있다. 마찬가지로 호출된 Activity는 Intent를 사용하여 값을 반환할 수 있다. 여기서는 startActivityForResult를 사용하여 두 Activity간 연동하는 방법을 살펴 보자.
호출하는 Activity를 A Activity라고 하고 호출받는 Activity를 B Activity라고 해보자.
A Activity에서 B Activity 호출
Intent intent = new Intent(getApplicationContext(), SettingActivity.class);
intent.putExtra("data", "전달하는 값"); //--- 전달할 값 저장
startActivityForResult(intent, 1);
String data = getIntent().getStringExtra("data"); //--- 전달받은 값
B Activity에서 A Activity로 반환
B Activity 구현
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;
}
}
public abstract class android.app.Service extends ContextWrapper implements ComponentCallbacks
정의
서비스는 백그라운드 작업을 처리 하거나 IPC (Inter-Process Communication)을 위한 원격 접속이 가능한 오브젝트를 만든다.
백그라운드 Service
private java.util.TimerTask task = new TimerTask() {
public void run() {
}
}
private java.util.Timer timer = new Timer(); timer.schedule(task, 5000); ```
IPC용 Service
private final ISimpleMathService.Stub binder = new ISimpleMathService.Stub() { 구현 }
return this.binder;
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;
}
}
package com.msi.manning.binder;
interface ISimpleMathService {
int add([](in)int a, out int b, inout int c)
}
ISimpleMathService
ISimpleMathService.Stub : Local
ISimpleMathService asInterface(IBinder b)
ISimpleMathService.Stub.Proxy : Remote
public abstract class android.content.BroadcastReceiver
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는 Java로 되어 있어 Java에서 제공하는 기능을 사용하여 Thread를 구현할 수 있습니다. 그러나, 안드로이드 화면의 각 요소(View)에 정보를 표시한다든지 하는 UI와 관련된 작업을 하는 경우에는 여러가지 제약 사항이 따릅니다.
Thread에서 UI 처리를 하기 위해서는 반드시 Activity 내에서 구현이 되어야 합니다.new Thread(new Runnable() {
public void run() {
view.post(new Runnable() {
public void run() {
view.setText("hello");
}
});
}
}).start();
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
view.setText("hello");
}
});
}
}).start();
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();
android.os.Message
Runnable
android.os.Looper
ANR (Application Not Responding, 응답없는 애플리케이션)
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();
Google에서는 AsyncTask라는 것을 제공하여 Android에서 UI 작업과 관련된 Thread의 구현을 손쉽게 할 수 있도록 지원 합니다.
UI Thread를 구현하기 위해서는 해당 Thread가 Activity에서 구현이 되어야 하며, 주고 받는 인자들의 타입이 일치 하여야 합니다. 아래 설명에서는 서로 일치해야 하는 인자들의 경우에는 동일한 색으로 표시를 해서 구분 합니다.
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();
}
}
- 참고 문헌
- [안드로이드 020. Thread 구현하기 1/2 (with ProgressBar), 2010.3](http://tigerwoods.tistory.com/26)
- [안드로이드 021: Thread 구현하기 2/2 (with AsyncTask & ProgressBar), 2010.3](http://tigerwoods.tistory.com/28)
## AndroidManifest.xml
- Root 폴더에 존재하며 애플리케이션의 환경, Activity, Service, BroadcastReceiver, ContentProvider, Permission 등을 정의
- ,
Preference 종류
res/xml/settings.xml
android:summary="상세 설명 1"
android:defaultValue="27"
android:dialogTitle="@string/dialog_title_edittext_preference" />
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");
참고 문헌
{|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