public final Class<?> getClass() {//Remove <?>
return shadow$_klass_;
}
Remove the <?> and refresh the project. The red lines should be gone.
public final Class getClass() {//<?> removed
return shadow$_klass_;
}
public final Class<?> getClass() {//Remove <?>
return shadow$_klass_;
}
Remove the <?> and refresh the project. The red lines should be gone.
public final Class getClass() {//<?> removed
return shadow$_klass_;
}
mChildFragmentManager = null;added in method Fragment#initState().
public class NestingFragment extends Fragment {
//...other codes
private FragmentManager retainedChildFragmentManager;
private FragmentHostCallback currentHost;
private Class fragmentImplClass;
private Field mHostField;
{
//Prepare the reflections to manage hiden fileds
try {
fragmentImplClass = Class.forName("android.support.v4.app.FragmentManagerImpl");
mHostField = fragmentImplClass.getDeclaredField("mHost");
mHostField.setAccessible(true);
} catch (ClassNotFoundException e) {
throw new RuntimeException("FragmentManagerImpl is renamed due to the " +
"change of Android SDK, this workaround doesn't work any more. " +
"See the issue at " +
"https://code.google.com/p/android/issues/detail?id=74222", e);
} catch (NoSuchFieldException e) {
throw new RuntimeException("FragmentManagerImpl.mHost is found due to the " +
"change of Android SDK, this workaround doesn't work any more. " +
"See the issue at " +
"https://code.google.com/p/android/issues/detail?id=74222", e);
}
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
protected FragmentManager childFragmentManager() {
if (retainedChildFragmentManager == null) {
retainedChildFragmentManager = getChildFragmentManager();
}
return retainedChildFragmentManager;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (retainedChildFragmentManager != null) {
//restore the last retained child fragment manager to the new
//created fragment
try {
//Copy the mHost(Activity) to retainedChildFragmentManager
currentHost = (FragmentHostCallback) mHostField.get(getFragmentManager());
Field childFMField = Fragment.class.getDeclaredField("mChildFragmentManager");
childFMField.setAccessible(true);
childFMField.set(this, retainedChildFragmentManager);
refreshHosts(getFragmentManager());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
//Refresh children fragment's hosts
} else {
//If the child fragment manager has not been retained yet, let it hold the internal
//child fragment manager as early as possible. This can prevent child fragment
//manager from missing to be set and then retained, which could happen when
//OS kills activity and restarts it. In this case, the delegate fragment restored
//but childFragmentManager() may not be called so mRetainedChildFragmentManager is
//yet set. If the fragment is rotated, the state of child fragment manager will be
//lost since mRetainedChildFragmentManager hasn't set to be retained by the OS.
retainedChildFragmentManager = getChildFragmentManager();
}
}
private void refreshHosts(FragmentManager fragmentManager) throws IllegalAccessException {
if (fragmentManager != null) {
replaceFragmentManagerHost(fragmentManager);
}
//replace host(activity) of fragments already added
List frags = fragmentManager.getFragments();
if (frags != null) {
for (Fragment f : frags) {
if (f != null) {
try {
//Copy the mHost(Activity) to retainedChildFragmentManager
Field mHostField = Fragment.class.getDeclaredField("mHost");
mHostField.setAccessible(true);
mHostField.set(f, currentHost);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
if (f.getChildFragmentManager() != null) {
refreshHosts(f.getChildFragmentManager());
}
}
}
}
}
//replace host(activity) of the fragment manager so that new fragments it creates will be attached
//with correct activity
private void replaceFragmentManagerHost(FragmentManager fragmentManager) throws IllegalAccessException {
if (currentHost != null) {
mHostField.set(fragmentManager, currentHost);
}
}
//...other codes
}
ActivityCycle﹕ onCreate: bundle=null
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=null
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onPostCreate: bundle=null
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments`
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDestroy
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=Object
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=Object
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=Object
FragmentCycle===>﹕ onActivityCreated: bundle=Object
FragmentCycle===>﹕ onViewStateRestored: bundle=Object
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onRestart
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreate: bundle=null
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=null
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onPostCreate: bundle=null
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onRestart
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreate: bundle=null
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=null
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onPostCreate: bundle=null
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDestroy
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=Object
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=Object
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=Object
FragmentCycle===>﹕ onActivityCreated: bundle=Object
FragmentCycle===>﹕ onViewStateRestored: bundle=Object
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onCreate: bundle=null
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=null
FragmentCycle===>﹕ onCreateView: bundle=null
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=null
FragmentCycle===>﹕ onActivityCreated: bundle=null
FragmentCycle===>﹕ onViewStateRestored: bundle=null
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onPostCreate: bundle=null
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDestroy
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=Object
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=Object
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=Object
FragmentCycle===>﹕ onActivityCreated: bundle=Object
FragmentCycle===>﹕ onViewStateRestored: bundle=Object
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onPause
FragmentCycle===>﹕ onPause
ActivityCycle﹕ onWindowFocusChanged
ActivityCycle﹕ onSaveInstanceState: outState=Object
FragmentCycle===>﹕ onSaveInstanceState: outState=Object
ActivityCycle﹕ onStop
FragmentCycle===>﹕ onStop
ActivityCycle﹕ onDestroy
FragmentCycle===>﹕ onDestroyView
FragmentCycle===>﹕ onDestroy
FragmentCycle===>﹕ onDetach
ActivityCycle﹕ onDetachedFromWindow
ActivityCycle﹕ onCreate: bundle=Object
FragmentCycle===>﹕ onAttach
ActivityCycle﹕ onAttachFragment
FragmentCycle===>﹕ onCreate: bundle=Object
ActivityCycle﹕ onCreateView Called many times here
ActivityCycle﹕ onStart
FragmentCycle===>﹕ onCreateView: bundle=Object
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
FragmentCycle===>﹕ onViewCreated: bundle=Object
FragmentCycle===>﹕ onActivityCreated: bundle=Object
FragmentCycle===>﹕ onViewStateRestored: bundle=Object
FragmentCycle===>﹕ onStart
ActivityCycle﹕ onRestoreInstanceState: bundle=Object
ActivityCycle﹕ onPostCreate: bundle=Object
ActivityCycle﹕ onResume
ActivityCycle﹕ onPostResume
ActivityCycle﹕ onResumeFragments
FragmentCycle===>﹕ onResume
ActivityCycle﹕ onAttachedToWindow
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onCreateView
ActivityCycle﹕ onWindowFocusChanged
public class Video {
private String mName;
private int Duration;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public int getDuration() {
return Duration;
}
public void setDuration(int duration) {
Duration = duration;
}
}
public class VideoPlayerState {
// ViewModel State Model contains a data model
private Video mCurrentVideo;
private boolean mPlaying;
public Video getCurrentVideo() {
return mCurrentVideo;
}
public void setCurrentVideo(Video currentVideo) {
mCurrentVideo = currentVideo;
}
public boolean isPlaying() {
return mPlaying;
}
public void setPlaying(boolean playing) {
mPlaying = playing;
}
}
public interface VideoPlayerViewModelEvent extends BaseViewModelEvent<VideoPlayerState> {
void onVideoPlayed(Video video);
void onVideoPaused(Video video);
}
The ViewModel
public class VideoPlayerViewModel extends
BaseViewModel<VideoPlayerViewModelEvent, VideoPlayerState> {
public void playVideo() {
if (mModel != null) {
if (!mModel.isPlaying()) {
mModel.setPlaying(true);
for (VideoPlayerViewModelEvent evet : this) {
evet.onVideoPlayed(mModel.getCurrentVideo());
}
}
}
}
public void pauseVideo() {
if (mModel != null) {
if (mModel.isPlaying()) {
mModel.setPlaying(false);
for (VideoPlayerViewModelEvent evet : this) {
evet.onVideoPaused(mModel.getCurrentVideo());
}
}
}
}
}
public class VideoPlayerView extends Activity implements OnClickListener {
private static ObjectMapper sMapper;
private static final String KEY_STATE_JSON = "KeyStateJson";
private static final String TAG = VideoPlayerView.class.getSimpleName();
private TextView mTextPlayingVideo;
private TextView mTextVideoLen;
private ImageView mPlayingButton;
private Button mBtnLoadVideo;
private VideoPlayerViewModel mViewModel;
private VideoPlayerViewModelEvent mEvent;
private VideoPlayerState mVideoPlayerState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlayingButton = (ImageView) findViewById(R.id.imgPlayerButton);
mPlayingButton.setOnClickListener(this);
mTextPlayingVideo = (TextView) findViewById(R.id.txtPlayingVideoTitle);
mTextVideoLen = (TextView) findViewById(R.id.txtVideoLength);
mTextPlayingVideo.setOnClickListener(this);
mBtnLoadVideo = (Button) findViewById(R.id.btnLoadVideo);
mBtnLoadVideo.setOnClickListener(this);
mViewModel = new VideoPlayerViewModel();
// Setup events handler for the view models
mEvent = new VideoPlayerViewModelEvent() {
@Override
public void onDataBound(VideoPlayerState dataModel) {
if (dataModel == null) {
mTextPlayingVideo.setText("No Video");
mTextVideoLen.setText("0s");
mPlayingButton.setImageResource(R.drawable.video_play_drawable);
mBtnLoadVideo.setText("Load Video");
} else {
if (dataModel.getCurrentVideo() != null) {
mTextPlayingVideo.setText(dataModel.getCurrentVideo().getName());
mTextVideoLen.setText(dataModel.getCurrentVideo().getDuration() + "s");
mPlayingButton.setImageResource(R.drawable.video_pause_drawable);
}
mBtnLoadVideo.setText("Unload Video");
}
}
@Override
public void onVideoPlayed(Video video) {
mTextPlayingVideo.setText(video.getName());
mPlayingButton.setImageResource(R.drawable.video_pause_drawable);
Toast.makeText(getApplicationContext(), video.getName() + " is played.",
Toast.LENGTH_SHORT).show();
}
@Override
public void onVideoPaused(Video video) {
mPlayingButton.setImageResource(R.drawable.video_play_drawable);
Toast.makeText(getApplicationContext(), video.getName() + " is paused.",
Toast.LENGTH_SHORT).show();
}
};
// Register events.
mViewModel.registerEvent(mEvent);
// Use JSON to serialize state which is easy and quick, if too slow
// replace it by Parcealable instead.
if (savedInstanceState == null) {
// Check if invoking activity send a video to play
if (getIntent() != null) {
if (getIntent().hasExtra(KEY_STATE_JSON)) {
try {
mVideoPlayerState = getMapper().readValue(
getIntent().getStringExtra(KEY_STATE_JSON), VideoPlayerState.class);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
} else {
// Restore the instance state when
// 1. rotating the phone,
// 2. back from background when it's killed by OS
// This can be done in a base class for all view
if (savedInstanceState.containsKey(KEY_STATE_JSON)) {
try {
mVideoPlayerState = getMapper().readValue(
savedInstanceState.getString(KEY_STATE_JSON), VideoPlayerState.class);
mViewModel.bindData(mVideoPlayerState);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
// No pre set player state, create a new one for testing.
if (mVideoPlayerState == null) {
mVideoPlayerState = new VideoPlayerState();
Video video = new Video();
video.setName("Test Video");
video.setDuration(90);
mVideoPlayerState.setCurrentVideo(video);
}
}
// Remember to save instance state. Using static is dangerous as Android OS
// will clear it in background. If you rely on them, you will find they
// suddenly turned null when app came back from the background after a long
// time period.
// This can be done in a base class for all view
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mViewModel.getModel() != null) {
try {
outState.putString(KEY_STATE_JSON,
getMapper().writeValueAsString(mViewModel.getModel()));
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnLoadVideo:
// Load unload button clicked.
if (mViewModel.getModel() == null) {
mViewModel.bindData(mVideoPlayerState);
} else {
mViewModel.bindData(null);
}
break;
case R.id.imgPlayerButton:
// Play/Pause button clicked.
VideoPlayerState m = mViewModel.getModel();
if (m != null) {
if (!m.isPlaying()) {
mViewModel.playVideo();
} else {
mViewModel.pauseVideo();
}
} else {
mViewModel.bindData(mVideoPlayerState);
mViewModel.playVideo();
}
break;
default:
break; // do nothing
}
}
private static ObjectMapper getMapper() {
if (sMapper == null) {
sMapper = new ObjectMapper();
}
return sMapper;
}
}
bash ${ProjDirPath}/build_native.sh NDK_DEBUG=1 V=1it complained
"Program "[path]/bash" not found in PATH".However, we need to use build_native.sh to build the project because Cocos2dx team has done it well and it also configured paths for cocos2dx project(though you can do your own as long as you want to challenge yourself on this). So we need to find a way to run the build_native.sh.
bash ${ProjDirPath}/build_native.sh NDK_DEBUG=1 V=1
Hello all android developers, I just want to share my experience building android apk manually using sdk tools without using Eclipse. My original goal is motivated firstly by the desire to incorporate continuous integration aspect to Android development process and secondly to ditch the ADT eclipse plugin since the plugin auto-build process blocks Eclipse UI if you have large resources, assets in your Android project, and a slow computer like mine. I am using CruiseControl as my continuous integration tool.
Below is one of the many apk build processes:
Build process
The good thing about building manually your apk is that you don’t have to name your resources directory to res, you can name it anything you want.
You can find ant scripts in:
Step 1: Generate Resource java code and packaged Resources
aapt package -f -M ${manifest.file} -F ${packaged.resource.file} -I ${path.to.android-jar.library} -S ${android-resource-directory} [-m -J ${folder.to.output.the.R.java}]
Step 2: Compile java source codes + R.java
use javac
Step 3: Convert classes to Dalvik bytecodes
use dx.bat
dx.bat –dex –output=${output.dex.file} ${compiled.classes.directory} ${jar files..}
Step 4: Create unsigned APK
use apkbuilder
apkbuilder ${output.apk.file} -u -z ${packagedresource.file} -f ${dex.file}
or
apkbuilder ${output.apk.file} -u -z ${packagedresource.file} -f ${dex.file} -rf ${source.dir} -rj ${libraries.dir}
-rf = resources required for compiled source files?
-rj = resources required for jar files
Step 6: Generate a key
use keytool
Step 7: Sign APK
use jarsigner
jarsigner -keystore ${keystore} -storepass ${keystore.password} -keypass ${keypass} -signedjar ${signed.apkfile} ${unsigned.apkfile} ${keyalias}
Step 8: Publish
use adb
adb -d install -r ${signed.apk}
Inspecting your APK file:
aapt list -v latest.apk
Open questions:
1. Can you include more than one dex file in the apk?
2. Can you have dex file named other than classes.dex in the apk?
3. Does an apk have to have a packaged resource?
Note: If upon installing your app using adb you see this error code FAILED_INSTALL_DEXOPT then most likely that either you don’t have classes.dex or you don’t have a packaged resource in the apk
See this post