Share
Embed
Component Pattern for Android
Component pattern is introduced by GameProgrammingPattern#14. I applied this pattern to Android Activity/Fragment.
mattak
March 23, 2017
Transcript
43 slides
-
class MainActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) this.setContentView(R.layout.activity_maps) } } プロジェクト作成時 -
class MainActivity : FragmentActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { var client:
GoogleApiClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.setContentView(R.layout.activity_maps) /* ... */ } override fun onStart() { super.onStart() /* ... */ } override fun onResume() { super.onResume() /* ... */ } override fun onConnected(bundle: Bundle?) { /* ... */ } override fun onConnectionSuspended(value: Int) { /* ... */ } override fun onConnectionFailed(result: ConnectionResult) { /* ... */ } } GoogleApiClient追加 -
class MainActivity : FragmentActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> {
var client: GoogleApiClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.setContentView(R.layout.activity_maps) /* ... */ } override fun onStart() { super.onStart() /* ... */ } override fun onResume() { super.onResume() /* ... */ } override fun onConnected(bundle: Bundle?) { /* ... */ } override fun onConnectionSuspended(value: Int) { /* ... */ } override fun onConnectionFailed(result: ConnectionResult) { /* ... */ } override fun onLocationChanged(location: Location?) { /* ... */ } override fun onResult(result: LocationSettingsResult) { /* ... */ } } LocationAPI追加 -
class MainActivity : FragmentActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult>, OnMapReadyCallback {
var client: GoogleApiClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.setContentView(R.layout.activity_maps) /* ... */ /* ... */ } override fun onStart() { super.onStart() /* ... */ } override fun onResume() { super.onResume() /* ... */ } override fun onConnected(bundle: Bundle?) { /* ... */ } override fun onConnectionSuspended(value: Int) { /* ... */ } override fun onConnectionFailed(result: ConnectionResult) { /* ... */ } override fun onLocationChanged(location: Location?) { /* ... */ } override fun onResult(result: LocationSettingsResult) { /* ... */ } override fun onMapReady(client: GoogleMap?) { /* ... */ } } GoogleMap追加 -
1. 継承分離による解決 MainActivity FragmentActivity class MainActivity : FooSDKActivity() FooSDKActivity class
FooSDKActivity : FragmentActivity() -
1. 継承分離による解決 - 継承がかぶると詰む (外部SDKとか - 継承元に密に依存する - 無限に継承が増える -
テスタビリティが低い - 各要素の独立性を確保できない -
3. 外部クラスによる解決 Activity.onCreate() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Class1.setup(this)
Class2.setup(this) // … } Class1.setup() Class2.setup() Activity.onResume() Class1.connect() Class3.run() … -
Componentにライフサイクルが移譲されている public class MyComponent : MonoBehaviour { void Awake() {
} void Start() { } void Update() { } void FixedUpdate() { } void OnApplicationFocus(bool focusStatus) { } } -
Componentの定義 public interface Component { void onComponentsAssigned(Components components); void
onCreate(Activity activity, Bundle savedInstanceState); void onStart(Activity activity); void onRestart(Activity activity); void onResume(Activity activity); void onPause(Activity activity); void onStop(Activity activity); void onDestroy(Activity activity); } -
空基底クラスをつくってやる public class BaseComponent implements Component { @Override public
void onCreate(Activity activity, Bundle savedInstanceState) {} @Override public void onStart(Activity activity) {} // … } -
Componentsを実装する public class Components implements Component { private Component[] components;
public Components(Component... components) { this.components = components; } @Override public void onCreate(Activity activity, Bundle savedInstanceState) { for (Component component : this.components) { component.onCreate(activity, savedInstanceState); } } @Override public void onStart(Activity activity) { for (Component component : this.components) { component.onStart(activity); } } // ... } -
必要なライフサイクルで呼び出し class ExampleActivity : FragmentActivity() { val component: Component =
AppComponents() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) component.onCreate(this, savedInstanceState) } override fun onStart() { super.onStart() component.onStart(this) } override fun onResume() { super.onResume() component.onStart(this) } // .... } -
getComponentで取得 class SampleComponent : BaseComponent() { override fun onCreate(activity: Activity?,
savedInstanceState: Bundle?) { val another = this.getComponent(AnotherComponent::class.java) // DO SOMETHING } } -
Activityの実装 class MainActivity : FragmentActivity() { private val mAppComponents =
AppComponents() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_maps) this.mAppComponents.onCreate(this, savedInstanceState) } override fun onStart() { super.onStart() this.mAppComponents.onStart(this) } override fun onResume() { super.onResume() this.mAppComponents.onResume(this) } override fun onRestart() { super.onRestart() this.mAppComponents.onRestart(this) } override fun onPause() { super.onPause() this.mAppComponents.onPause(this) } override fun onStop() { super.onStop() this.mAppComponents.onStop(this) } override fun onDestroy() { super.onDestroy() this.mAppComponents.onDestroy(this) } } 基本Lifecycleのみなら これ以上増えない