@mSolo
2015-04-23T07:54:02.000000Z
字数 5879
阅读 1582
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;
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("someVar", someVar);
outState.putString(“text”, tv1.getText().toString());
}
@Override
public 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中保存这些数据。
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 这里保存数据
}
@Override
public void onDestroyView() {
super.onDestroyView();
// 如果onSaveInstanceState没被调用,这里也可以保存数据
}
但是问题来了onSaveInstanceState中保存数据很简单,因为它有Bundle参数,但是onDestroyView没有,那保存在哪里呢?
Bundle savedState;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!restoreStateFromArguments()) {
// First Time running, Initialize something here
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveStateToArguments(); // Save State Here
}
@Override
public 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);
}
}