본 포스팅은 DroidKaigi 2017 ~ Build my own debugging tool on overlay 을 기본으로 번역하여 작성했습니다
제 일본어 실력으로 인하여 오역이나 오타가 발생할 수 있습니다.
Keishin Yokomaku
~ DroidKaigi 2017 DAY.02 - Room 2
BUILDING MY OWN DEBUGGING TOOL ON OVERLAY
내가 만들고 싶어 😄
특별한 Layer에 View를 표시한다
<uses-permission>
너무 많다 😂😂
public class MainActivity extends Activity {
private View mOverlayView;
private WindowManager mWindowManager;
@Override
protected void onCreate(Bundle icicle) {
// ……
WindowManager.LayoutParams p = new WM.LP(
WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG,
FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT
);
mWindowManager.addView(mOverlayView, p);
}
}
public class MainActivity extends Activity {
private View mOverlayView;
private WindowManager mWindowManager;
@Override
protected void onDestroy() {
// ……
mWindowManager.removeView(mOverlayView);
}
}
Background에서 View를 계속 갱신
→ Service로 View를 WindowManager에 건네면 다른 앱에 겹쳐서 계속 표시할 수 있다
Activity가 해주는 것을 Service로 재구현한다
<manifest package=“”>
<application>
<activity
android:name=“.MyActivity”
android:configChanges=“keyboard|
keyboardHidden|screenLayout|screenSize|
orientation|density|fontScale|layoutDirection|
locale|mcc|mnc|navigation|smallestScreenSize|
touchScreen|uiMode”/>
</application>
</manifest>
Service | OverlayViewManager | WindowManager | ||
---|---|---|---|---|
onCreate | ▶ | create | ▶ | addView |
configChanges | ▶ | configChanges | ▶ | updateViewLayout |
onDestroy | ▶ | destroy | ▶ | removeView |
public class OverlayViewManager {
private final Context mContext; // Service
private final WindowManager mWindowManager;
private final WindowManager.LayoutParams mParams;
private View mRootView;
public void create() {
mRootView = LayoutInflater.from(mContext).inflate(R.layout.view_root_overlay, null, false);
mWindowManager.addView(mRootView, mParams)
}
}
public class OverlayViewService extends Service {
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent i) {
mOverlayViewManager.changeConfiguration();
}
}
}
public class OverlayViewService extends Service {
private final BroadcastReceiver mReceiver = //…
@Override
public void onCreate() {
//……
IntentFilter filter = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGE);
registerReceiver(mReceiver, filter);
}
}
public class OverlayViewService extends Service {
private final BroadcastReceiver mReceiver = //…
@Override
public void onDestroy() {
//……
unregisterReceiver(mReceiver);
}
}
public class OverlayViewManager {
private final Context mContext; // Service
private Context mThemedContext;
private View mRootView;
public void create() {
mThemedContext = new OverlayViewContext(mContext);
mRootView = LayoutInflater.from(mThemedContext).inflate(R.layout.view_root_overlay, null, false);
}
}
/* package */ class OverlayViewContext extends ContextThemeWrapper {
public OverlayViewContext(Context base) {
super(context, R.style.AppTheme);
}
}
/* package */ class OverlayViewContext extends ContextThemeWrapper {
private LayoutInflater mInflater;
@Override
public Object getSystemServcie(String name) {
// ……
}
}
private LayoutInflater mInflater;
@Override
public Object getSystemServcie(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(
getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return super.getSystemService(name);
}
프로세스를 계속 움직이게 한다
Activity 등과 연결
public class DebugOverlayService extends Service {
public static final String EXTRA_DATA = // ……
private OverlayViewManager mManager;
@Override
public int onStartCommand(Intent i, int flags, int startId) {
// ……
Data data = i.getParcelableExtra(EXTRA_DATA);
mManager.onReceiveData(data);
}
}
public class DebugOverlayView extends RelativeLayout {
private EventBus;
@Subscribe
public void onDataReceived(Data data) {
// draw something from data
}
}
ServiceScope | ApplicationScope | ActivityScope | ||
---|---|---|---|---|
listen | ◀ | LogEmitter | ◀ | send |
정리
Keishin Yokomaku
~ DroidKaigi 2017 DAY.02 - Room 2
comments powered by Disqus
Subscribe to this blog via RSS.