안드로이드 프레임워크 프로그래밍(5) [Toast 구현하기]

 지난 포스팅에서 새로 추가한 System service를 적용하여 Log를 통해 등록한 System service가 제대로 동작하는지에 대해 알아보았습니다. 이번에는 Framework 자체에서 Toast를 구현하는 작업을 해보도록 하겠습니다.


※본 포스팅은 지난 포스팅에서 사용하였던 예제를 수정하여 적용하였습니다. 그러므로 본 포스팅에서는 수정된 코드에 대해서만 다룰 것이며 상세한 코드는 이전 포스팅을 통해 확인해 주시기 바랍니다.


http://elecs.tistory.com/64


1. System service에 Toast 관련 소스를 입력합니다.

frameworks/base/services/java/com/android/server/TestService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.android.server;
import android.content.Context;
import android.os.Handler;
import android.os.ITestService;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
public class TestService extends ITestService.Stub {
    private static final String TAG = "TestService";
    private TestWorkerThread mWorker;
    private TestWorkerHandler mHandler;
    private Context mContext;
    public TestService(Context context) {
        super();
        mContext = context;
        mWorker = new TestWorkerThread("TestServiceWorker");
        mWorker.start();
        Log.i(TAG, "Spawned worker thread");
    }
 
    public void setValue(int val) {
        Log.i(TAG, "setValue " + val);
        Message msg = Message.obtain();
        msg.what = TestWorkerHandler.MESSAGE_SET;
        msg.arg1 = val;
        mHandler.sendMessage(msg);
    }
 
    public void showToast(int val){
        Log.i(TAG, "showToast " + val);
        Message msg = Message.obtain();
        msg.what = 2;
        msg.arg1 = val;
        mHandler.sendMessage(msg);
    }
 
    private class TestWorkerThread extends Thread {
        public TestWorkerThread(String name) {
            super(name);
        }
        public void run() {
            Looper.prepare();
            mHandler = new TestWorkerHandler();
            Looper.loop();
        }
    }
 
    private class TestWorkerHandler extends Handler {
        private static final int MESSAGE_SET = 0;
        @Override
        public void handleMessage(Message msg) {
            try {
                if (msg.what == MESSAGE_SET) {
                    Log.i(TAG, "set message received: " + msg.arg1);
                }
        if (msg.what == 2){
            Log.i(TAG, "Show toast!!");
            Toast.makeText(mContext, "Toast message : "+msg.arg1, Toast.LENGTH_SHORT).show();
        }
        
            } catch (Exception e) {
                // Log, don't crash!
                Log.e(TAG, "Exception in TestWorkerHandler.handleMessage:", e);
            }
        }
    }
}
cs


2. AIDL 또한 변경된 System service 프로그램에 맟게 method를 추가합니다.

frameworks/base/core/java/android/os/ITestService.aidl

1
2
3
4
5
6
7
8
package android.os;
interface ITestService {
/**
* {@hide}
*/
    void setValue(int val);
    void showToast(int val);
}
cs



3. 여기까지 진행하셨다면 작성한 소스를 Build 해줍니다.

$ make -j4


4. 애플리케이션 프로젝트를 통해 Framework에서 Toast를 구현하는 프로그램을 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.example.test;
 
import android.app.Activity;
import android.app.ActivityThread;
import android.os.Bundle;
import android.os.ITestService;
import android.os.ServiceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.util.Log;
 
 
public class MainActivity extends Activity {
    private static final String DTAG = "HelloServer";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test"));
        try{
            Log.d(DTAG, "Going to call service");
            om.setValue(20);
            om.showToast(30);
            Log.d(DTAG, "Service called successfully");
        }catch(Exception e){
            Log.d(DTAG, "FAILED to call service");
            e.printStackTrace();
        }
        
    }
 
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
 
}
cs



이제 어플리케이션을 실행하면 다음과 같은 결과를 확인하실 수 있습니다.