@mSolo
2015-04-22T23:54:02.000000Z
字数 5879
阅读 1685
Android 网络文章
摘录,版权所属:Android最佳实践
<resources><!-- grayscale --><color name="white" >#FFFFFF</color><color name="gray_light">#DBDBDB</color><color name="gray" >#939393</color><color name="gray_dark" >#5F5F5F</color><color name="black" >#323232</color><!-- basic colors --><color name="green">#27D34D</color><color name="blue">#2A91BD</color><color name="orange">#FF9D2F</color><color name="red">#FF432F</color></resources>
<resources><!-- font sizes --><dimen name="font_larger">22sp</dimen><dimen name="font_large">18sp</dimen><dimen name="font_normal">15sp</dimen><dimen name="font_small">12sp</dimen><!-- typical spacing between two views --><dimen name="spacing_huge">40dp</dimen><dimen name="spacing_large">24dp</dimen><dimen name="spacing_normal">14dp</dimen><dimen name="spacing_small">10dp</dimen><dimen name="spacing_tiny">4dp</dimen><!-- typical sizes of views --><dimen name="button_height_tall">60dp</dimen><dimen name="button_height_normal">40dp</dimen><dimen name="button_height_short">32dp</dimen></resources>
摘录,版权所属:Android 加载图片时的内存问题
BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 3; //图片宽高都为原来的1/3
图片的压缩
bitmap.compress(Bitmap.CompressFormat.PNG, 80, outStream);图片用过之后要清除缓存,即使 GC 会定期进行垃圾回收,但由于图片处理过程中用到了java的库函数和c库函数,而c库函数所占用的内存无法通过垃圾回收来释放,所以特别是对于大的图片,因此要在使用完之后手动回收其内存空间,否则将会导致内存泄露
public void clearMemery(Bitmap bitmap) {if (bitmap != null && !bitmap.isRecycled()) {bitmap.recycle();bitmap = null;}}
FileInputStream fis = new FileInputStream(/sdcard/test.png);Bitmap bitmap = BitmapFactory.decodeStream(fis);InputStream inputStream=getBitmapInputStreamFromSDCard("test.png");Bitmap bitmap = BitmapFactory.decodeStream(inputStream);Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);String SDCarePath=Environment.getExternalStorageDirectory().toString();String filePath=SDCarePath+"/"+"test.png";Bitmap bitmap = BitmapFactory.decodeFile(filePath, null);Bitmap bitmap = BitmapFactory.decodeStream(getClass().getResourceAsStream("/res/drawable/test.png"));
摘录,版权所属:Android中保存和恢复Fragment状态的最好方法
这种情况非常简单,你只需在onSaveInstanceState存储会在旋转的时候会丢失的数据,包括变量,然后在onActivityCreated或者onViewStateRestored中取出来:
int someVar;@Overrideprotected void onSaveInstanceState(Bundle outState) {outState.putInt("someVar", someVar);outState.putString(“text”, tv1.getText().toString());}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);someVar = savedInstanceState.getInt("someVar", 0);tv1.setText(savedInstanceState.getString(“text”));}
看起来很简单是吧,但是存在这样的情况,View重建,但是onSaveInstanceState未被调用,这意味着UI上的所有东西都丢失了,请看下面的情景二。
当Fragment从回退栈中返回的时候,onDestroyView和onCreateView被调用,但是onSaveInstanceState貌似没有被调用,这就导致了一切UI数据都回到了xml布局中定义的初始状态。当然,那些内部实现了状态保存的view,比如有android:freezeText属性的EditText和TextView,仍然可以保持其状态,因为Fragment可以为他们保持数据,但是开发者没法获得这些事件,我们只能手动的在onDestroyView中保存这些数据。
@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);// 这里保存数据}@Overridepublic void onDestroyView() {super.onDestroyView();// 如果onSaveInstanceState没被调用,这里也可以保存数据}
但是问题来了onSaveInstanceState中保存数据很简单,因为它有Bundle参数,但是onDestroyView没有,那保存在哪里呢?
Bundle savedState;@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);if (!restoreStateFromArguments()) {// First Time running, Initialize something here}}@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);saveStateToArguments(); // Save State Here}@Overridepublic void onDestroyView() {super.onDestroyView();saveStateToArguments(); // Save State Here}private void saveStateToArguments() {savedState = saveState();if (savedState != null) {Bundle b = getArguments();b.putBundle(“internalSavedViewState8954201239547”, savedState);}}private boolean restoreStateFromArguments() {Bundle b = getArguments();savedState = b.getBundle(“internalSavedViewState8954201239547”);if (savedState != null) {restoreState();return true;}return false;}// 取出状态数据private void restoreState() {if (savedState != null) {//比如,tv1.setText(savedState.getString(“text”));}}// 保存状态数据private Bundle saveState() {Bundle state = new Bundle();// 比如,state.putString(“text”, tv1.getText().toString());return state;}
现在你可以轻松的在fragment的saveState和restoreState中分别存储和取出数据了。现在看起来好多了,几乎快要成功了,但是还有更极端的情况。
当你旋转一次屏幕,onSaveInstanceState被调用,UI的状态会如预期的那样被保存,但是当你再一次旋转屏幕,上面的代码就可能会崩溃。原因是虽然onSaveInstanceState被调用了,但是当你旋转屏幕,回退栈中Fragment的view将会销毁,同时在返回之前不会重建。这就导致了当你再一次旋转屏幕,没有可以保存数据的view。saveState()将会引用到一个不存在的view而导致空指针异常NullPointerException,因此需要先检查view是否存在。如果存在保存其状态数据,将Argument中的数据再次保存一遍,或者干脆啥也不做,因为第一次已经保存了。
private void saveStateToArguments() {if (getView() != null)savedState = saveState();if (savedState != null) {Bundle b = getArguments();b.putBundle(“savedState”, savedState);}}