Rox*_*era 6 android orientation
我有一个应用程序,我从一个捕获图像的教程中复制了MediaStore.ACTION_IMAGE_CAPTURE.当我在手机上运行应用程序时,我有一些奇怪的感觉.
即使我没有移动手机,相机应用程序本身也会在操作过程中翻转其方向几次.在返回教程应用程序之前,它会简要地进入横向模式.因此,教程应用程序在控制返回到它后会回到纵向模式,并且图像丢失.我尝试将相机活动的方向设置为横向,图像不会丢失.
但该应用程序的布局适用于纵向模式.或者,如果我在拍摄照片的同时横向握住相机,我可以在应用程序恢复焦点后转动手机,而不会丢失图像.
我在网上做了一些讨论.Stackoverflow上有人提到方向的改变引起了额外的调用onCreate." onCreate()被调用的原因是因为当您在纵向方向上调用相机活动时,它将改变方向并破坏您之前的活动." 我在调试模式下运行应用程序,在onCreate和onActivityResult方法中设置了断点.onCreate当我以肖像模式拍摄照片时,确实会被调用.调用的顺序是onCreate,onActivityResult,onCreate.如果我以横向模式拍摄照片(这是我的相机应用程序以任何方式结束的地方),onCreate不会被调用.现在我已经知道发生了什么,我该如何避免这个问题?这是应用程序现在的样子:
package com.example.testapp;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
public class CameraActivity extends Activity implements View.OnClickListener {
ImageButton ib;
Button b;
ImageView iv;
Intent i;
final static int cameraData = 0;
Bitmap bmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_activity);
initialize();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
setContentView(R.layout.photo_activity);
initialize();
}
private void initialize() {
iv = (ImageView)findViewById(R.id.imageViewReturnedPicture);
ib = (ImageButton)findViewById(R.id.imageButtonTakePicture);
b = (Button)findViewById(R.id.buttonSetWallpaper);
b.setOnClickListener(this);
ib.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.buttonSetWallpaper:
try {
WallpaperManager wm = WallpaperManager.getInstance(getApplicationContext());
wm.setBitmap(bmp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.imageButtonTakePicture:
i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
bmp = (Bitmap)extras.get("data");
iv.setImageBitmap(bmp);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我在此活动清单中的内容:
android:name="com.example.testapp.CameraActivity"
android:label="Camera Activity"
android:configChanges="orientation"
android:screenOrientation="portrait"
我已经做了相当多的搜索,但我发现的大部分内容都缺乏具体的例子.我需要知道代码的样子,而不仅仅是要使用的功能.
我的手机是LG Motion.有没有其他人遇到这个问题?怎么修好?
Cab*_*zas 11
在清单中,在每个活动中我使用configChanges:
<activity
android:name=".MainActivity"
android:configChanges="screenLayout|orientation|screenSize">
Run Code Online (Sandbox Code Playgroud)
我希望这对你有所帮助.
您必须覆盖onRetainNonConfigurationInstance并使用getLastNonConfigurationInstance来保存/恢复位图.
像这样:
// during onCreate(Bundle), after initialise()
bmp = getLastNonConfigurationInstance();
if(bmp!=null){ iv.setImageBitmap(bmp); }
else { /* the image was not taken yet */ }
Run Code Online (Sandbox Code Playgroud)
那么你的活动你覆盖:
@Override
public Object onRetainNonConfigurationInstance (){
return bmp;
}
Run Code Online (Sandbox Code Playgroud)
这将在旋转期间"保存"位图.
编辑:
使用建议使用的onSaveInstanceState的示例但是不可取,因为它会占用大量内存而且速度很慢,但很快就会出现其他情况:
public class SomethingSomething extends Activity{
String name="";
int page=0;
// This is called when the activity is been created
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if you saved something on outState you can recover them here
if(savedInstanceState!=null){
name = savedInstanceState.getString("name");
page = savedInstanceState.getInt("page");
}
}
// This is called before the activity is destroyed
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("name", name);
outState.putInt("page", page);
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,这个解决方案对你的情况不利的原因是因为用于此的Android Bundle是Android特殊类型的序列化,它可以处理实现Parcelable的原语,字符串和类(这些类实际上只包含它们的原语) .即使你的Bitmaps实现Parcelable,也会花费大量时间将Bitmap上的每个字节复制到bundle中,并且会使Bitmap已经很大的内存消耗倍增.
现在让我们看一下使用的解决方案setRetainInstance(从您可以找到的示例中略微复制一下)\sdk\extras\android\support\samples\Support4Demos\src\com\example\android\supportv4\app\FragmentRetainInstanceSupport.Java.
一定要检查示例,因为它显示了一些其他花哨的技巧.
// This fragment will be managed by the framework but we won't built a UI for it.
public class FragRetained extends Fragment{
public static final String TAG = "TAG.FragRetained";
private Bitmap bitmap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Tell the framework to try to keep this fragment around
// during a configuration change.
setRetainInstance(true);
}
public Bitmap getBitmap() { return bitmap; }
public void setBitmap(Bitmap bmp) { bitmap = bmp; }
}
public class MyActivity extends Activity{
private FragRetained myFragRetained;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the content view
img = (ImageView)findViewById(R.id.byImgV);
myFragRetained = getFragmentManger.findFragmentByTag(FragRetained.TAG);
if(myFragRetained == null){
myFragRetained = new FragRetained ();
}else{
Bitmap b = myFragRetained.getBitmap();
if(b==null){
// the user still did not choose the photo
}else{
img.setImageBitmap(b);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
bmp = (Bitmap)extras.get("data");
iv.setImageBitmap(bmp);
myFragRetained.setBitmap(bmp);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并确保android:configChanges="orientation"从你的清单中删除该行,因为它可能会造成更大的危害,然后是一个小的引用:
注意:应避免使用此属性,并仅将其用作最后的手段.有关如何通过配置更改正确处理重新启动的详细信息,请阅读处理运行时更改.
您应该处理方向更改的方法是保存实例状态。如果您填写onSaveInstanceState方法,则可以在 onCreate 期间取回保存到该包中的数据。这是为您完成的视图,但其他数据您必须自己保存。任何原始的、可分割的或可序列化的对象都可以通过这种方式保存,包括位图。
您应该这样做不仅是为了在配置更改后幸存下来,而且还可以将您的状态保持在内存不足的情况下。
| 归档时间: |
|
| 查看次数: |
12739 次 |
| 最近记录: |