Android Rajawali纹理视图片段OnResume(),OnPause()
我有一个安卓应用程序,可以作为汽车显示器;由于车上安装了CAN总线系统,我在安卓系统中获得了不同的信号 我的公司要求我开发一个可以交互和监控所有输入和输出的应用程序 我有一个处理不同片段的活动 在主片段(HomeFragment)中,我要展示一个汽车的交互式3D模型 当我在互联网上寻找显示3D模型的方法时,我发现了这个名为 此“引擎”提供纹理和曲面视图。我决定使用纹理视图 我扩展了Rajawaly render类,在xml中添加了Rajawaly纹理视图,可以在其中显示obj文件,还可以翻译它们和相机 为了理解它是如何工作的,经过几个测试项目后,我决定在我正在开发的汽车监视器的HomeFragment中实现它 一切看起来都很好,工作正常,直到我移动,用其他碎片替换主碎片,当我返回主碎片时,我得到一个错误,它告诉我Android Rajawali纹理视图片段OnResume(),OnPause(),android,android-fragments,opengl-es,3d,rajawali,Android,Android Fragments,Opengl Es,3d,Rajawali,我有一个安卓应用程序,可以作为汽车显示器;由于车上安装了CAN总线系统,我在安卓系统中获得了不同的信号 我的公司要求我开发一个可以交互和监控所有输入和输出的应用程序 我有一个处理不同片段的活动 在主片段(HomeFragment)中,我要展示一个汽车的交互式3D模型 当我在互联网上寻找显示3D模型的方法时,我发现了这个名为 此“引擎”提供纹理和曲面视图。我决定使用纹理视图 我扩展了Rajawaly render类,在xml中添加了Rajawaly纹理视图,可以在其中显示obj文件,还可以翻译它们
尝试在空对象引用上调用虚拟方法“void org.rajawali3d.view.TextureView$GLThread.onResume()”
所以我的问题是,我应该如何在我的活动片段中管理Rajawaly TextureView
我发现文档真的很有趣,我不知道GitHub上的wiki指的是哪个版本的软件。有没有人能从这个库中得到具体的结果?有人知道在android应用程序中显示3D模型的其他方法吗
我快疯了,谢谢你的帮助,这里有一些代码:
HomeFragment的OnResume方法:
@Override
public void onResume() {
Log.e("DEBUG", "onResume of FragmentHome");
use_HandlerBinding(); //An Handler
BTNLuci.setEnabled(true); //Some Buttons
BTNClima.setEnabled(true); //Some Buttons
BTNServizi.setEnabled(true); //Some Buttons
if(rajawaliTextureView==null && renderer==null)
{
ProgressBar PB = (ProgressBar)getView().findViewById(R.id.PBrajawaly); //a progress bar
rajawaliTextureView = (TextureView) getView().findViewById(R.id.RajawalyTextureView);
renderer = new Renderer(getContext(),rajawaliTextureView,PB);
rajawaliTextureView.setSurfaceRenderer(renderer);
rajawaliTextureView.setOnTouchListener(renderer);
}
rajawaliTextureView.onResume();
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of FragmentHome");
rajawaliTextureView.onPause();
HandlerBinding.removeCallbacks(RunableHandlerBinding); //Some Handler
super.onPause();
}
OnPause:
@Override
public void onResume() {
Log.e("DEBUG", "onResume of FragmentHome");
use_HandlerBinding(); //An Handler
BTNLuci.setEnabled(true); //Some Buttons
BTNClima.setEnabled(true); //Some Buttons
BTNServizi.setEnabled(true); //Some Buttons
if(rajawaliTextureView==null && renderer==null)
{
ProgressBar PB = (ProgressBar)getView().findViewById(R.id.PBrajawaly); //a progress bar
rajawaliTextureView = (TextureView) getView().findViewById(R.id.RajawalyTextureView);
renderer = new Renderer(getContext(),rajawaliTextureView,PB);
rajawaliTextureView.setSurfaceRenderer(renderer);
rajawaliTextureView.setOnTouchListener(renderer);
}
rajawaliTextureView.onResume();
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of FragmentHome");
rajawaliTextureView.onPause();
HandlerBinding.removeCallbacks(RunableHandlerBinding); //Some Handler
super.onPause();
}
rajawaliSurfaceView和renderer是在片段中声明的两个静态istance,并在片段的OnCreateView中初始化
如果您需要更多代码,请询问,再次感谢
编辑:
@Override
public void onResume() {
Log.e("DEBUG", "onResume of FragmentHome");
use_HandlerBinding(); //An Handler
BTNLuci.setEnabled(true); //Some Buttons
BTNClima.setEnabled(true); //Some Buttons
BTNServizi.setEnabled(true); //Some Buttons
if(rajawaliTextureView==null && renderer==null)
{
ProgressBar PB = (ProgressBar)getView().findViewById(R.id.PBrajawaly); //a progress bar
rajawaliTextureView = (TextureView) getView().findViewById(R.id.RajawalyTextureView);
renderer = new Renderer(getContext(),rajawaliTextureView,PB);
rajawaliTextureView.setSurfaceRenderer(renderer);
rajawaliTextureView.setOnTouchListener(renderer);
}
rajawaliTextureView.onResume();
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of FragmentHome");
rajawaliTextureView.onPause();
HandlerBinding.removeCallbacks(RunableHandlerBinding); //Some Handler
super.onPause();
}
我已经尝试使用SetPreserveEGLContextOnPause(true)来保留纹理视图,以便在片段进入暂停()时删除其内容
它无法使它工作,可能是因为片段生命周期,所以我再次在这里发布我的代码
活动
这是我为在活动中添加或替换片段而调用的代码部分:
public void changeFragment(Fragment frag, boolean saveInBackstack, boolean animate) {
String backStateName = ((Object) frag).getClass().getName();
String TAG ="Fragment manager";
try {
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
//fragment not in back stack, create it.
FragmentTransaction transaction = manager.beginTransaction();
if (animate) {
Log.d(TAG, "Change Fragment: animate");
transaction.setCustomAnimations(R.anim.enter_from_left,R.anim.exit_from_right, R.anim.enter_from_right,R.anim.exit_from_left);
}
transaction.replace(R.id.fragment_holder, frag, backStateName);
if (saveInBackstack) {
Log.d(TAG, "Change Fragment: addToBackTack " + backStateName);
transaction.addToBackStack(backStateName);
} else {
Log.d(TAG, "Change Fragment: NO addToBackTack");
}
transaction.commit();
} else {
// custom effect if fragment is already instanciated
}
} catch (IllegalStateException exception) {
Log.w(TAG, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
}
}
FragmentHome
这是显示的第一个片段,它包含3D模型、Rajawaly纹理视图和渲染器:
TextureView RajawaliTextureView;
Renderer render;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.e("DEBUG", "onCreate of FragmentHome");
int result;
ActivityManager activityManager =
(ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
result= configInfo.reqGlEsVersion;
} else {
result= 1 << 16; // Lack of property means OpenGL ES version 1
}
Log.e("reqGlEsVersion", String.valueOf(result));
Log.e("getGlEsVersion", configInfo.getGlEsVersion());
SetUpRenderRajawali();
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("DEBUG", "onCreateView of FragmentHome");
// Inflate the layout for this fragment
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false);
View view = binding.getRoot();
(...)
RajawaliTextureView = (TextureView) view.findViewById(R.id.RajaView);
RajawaliTextureView.setSurfaceRenderer(render);
RajawaliTextureView.setPreserveEGLContextOnPause(true);
return view;
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of FragmentHome");
(...)
if(render!=null && RajawaliTextureView!=null) {
RajawaliTextureView.onResume();
render.onResume();
}
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of FragmentHome");
(...)
if(render!=null && RajawaliTextureView!=null) {
RajawaliTextureView.onPause();
render.onPause();
}
super.onPause();
}
private PointLight LuceGlobale;
private static Object3D ModelloAmbulanza;
private Object3D Container;
private Material MaterialeGenerico;
//RAJAWALI RENDERER
private void SetUpRenderRajawali()
{
render = new Renderer(getActivity()) {
@Override
protected void initScene() {
Container = new Object3D();
MaterialeGenerico = new Material();
MaterialeGenerico.enableLighting(true);
MaterialeGenerico.setDiffuseMethod(new DiffuseMethod.Lambert());
LuceGlobale = new PointLight();
LuceGlobale.setPosition(20, 40, 0);
LuceGlobale.setPower(15);
final LoaderOBJ loaderOBJ = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.xlink_obj);
loadModel(loaderOBJ, call, R.raw.xlink_obj);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
}
@Override
public void onTouchEvent(MotionEvent event) {
}
@Override
public void onRender(final long elapsedTime, final double deltaTime) {
super.onRender(elapsedTime, deltaTime);
try {
ModelloAmbulanza.rotate(Vector3.Axis.Y, 1.0);
}catch (Exception e)
{}
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onRenderSurfaceCreated(EGLConfig config, GL10 gl, int width, int height) {
super.onRenderSurfaceCreated(config, gl, width, height);
}
@Override
public void onRenderSurfaceDestroyed(SurfaceTexture surface) {
super.onRenderSurfaceDestroyed(surface);
}
};
}
@Override
public void onModelLoadComplete(ALoader aLoader) {
RajLog.d("Model load complete: " + aLoader);
final LoaderOBJ obj = (LoaderOBJ) aLoader;
ModelloAmbulanza = obj.getParsedObject();
ModelloAmbulanza.setPosition(0,0,0);
render.getCurrentScene().addChild(ModelloAmbulanza);
render.getCurrentCamera().setPosition(0,3,20);
render.getCurrentScene().setBackgroundColor((float)0.14, (float) 0.14,(float)0.14,0);
}
@Override
public void onModelLoadFailed(ALoader aLoader) {
RajLog.e("Model load failed: " + aLoader);
}
TextureView-rajawalitextreview;
渲染器渲染;
@凌驾
创建时的公共void(@Nullable Bundle savedInstanceState){
Log.e(“DEBUG”,“oncreateoffragmenthome”);
int结果;
活动管理器活动管理器=
(ActivityManager)getActivity().getSystemService(Context.ACTIVITY_服务);
ConfigurationInfo configInfo=activityManager.GetDeviceConfiguration信息();
if(configInfo.reqGlEsVersion!=ConfigurationInfo.GL\U ES\U版本\U未定义){
结果=configInfo.reqGlEsVersion;
}否则{
结果=1当您“返回到主片段”(假设它之前至少显示过一次)时,“FragmentHome的onResume”是否会显示在日志中?在这种情况下,是RajawaLiteTextReview null还是renderer null?您是否尝试过在每次调用onResume时重新创建RajawaliteTextReview(可能不是一个好的解决方案,但值得一试…?重新创建RajawalitextReview实际上是可行的,但a想要显示的对象非常大,解析器需要花费大量时间。另外,每次我暂停并恢复碎片时,内存使用量都会增加,具体取决于RajawalitextReview的制作方式,它可能会“丢失”暂停时它的OpenGLES上下文,因此需要在恢复时重新创建OpenGLES上下文,然后所有数据都必须重新上传到GPU,我不能告诉您更多的抱歉…我快速检查了github,请尝试调用RajawalitextReview.setPreserveEGLContextOnPause(true)
在创建rajawaliTextureView时,默认值为false,因此当调用onPause时,GLES上下文将被破坏。好的,很高兴知道我提供了帮助!请注意,setPreserveEGLContextOnPause(或类似解决方案)在Android游戏中被大量使用,以在用户最小化游戏时保留上下文(当游戏恢复时,通常不需要重新加载任何3D数据)。因此我倾向于说,允许上下文被破坏并尝试在恢复中“恢复”数据是处理此类问题的“老办法”(很久以前,你别无选择,只能让上下文被破坏,并在恢复时重新创建所有GPU纹理、缓冲区等)当你“返回主片段”(假设它之前至少显示过一次)时,“碎片主片段的恢复”是否显示在日志中?在这种情况下是RajawaLiteTextReview null还是renderer null?您是否尝试过在每次调用onResume时重新创建RajawaLiteTextReview(可能不是一个好的解决方案,但值得一试…)?重新创建RajawaritextureReview实际上是可行的,但要显示的对象非常大,解析器需要花费大量时间。另外,每次我暂停并恢复碎片时,内存使用量都会增加,这取决于RajawaritextureReview的制作方式,它可能会“丢失”暂停时它的OpenGLES上下文,因此需要在恢复时重新创建OpenGLES上下文,然后所有数据都必须重新上传到GPU,我不能告诉您更多的抱歉…我快速检查了github,请尝试调用RajawalitextReview.setPreserveEGLContextOnPause(true)
在创建rajawaliTextureView时,默认值为false,因此当调用onPause时,GLES上下文将被破坏。好的,很高兴知道我提供了帮助!请注意,setPreserveEGLContextOnPause(或类似的解决方案)在Android游戏中被大量使用来保存上下文w