我有一个Android应用程序,应该可以用作汽车监视器;由于车上安装了CAN总线系统,我得到了不同的信号进入android。
我公司要求我开发一个可以互动并监控所有输入和输出的应用程序。
我有一个处理不同片段的活动。
在主片段中,即HomeFragment,我将展示汽车的交互式3D模型。
在互联网上寻找显示3D模型的方法时,我发现这个库名为Rajawali。
这"引擎"提供纹理和表面视图。我决定使用纹理视图。
我扩展了Rajawaly渲染类,我在我的xml中添加了RajawalyTexture视图,我能够在其中显示obj文件,并且我能够翻译它们和相机。
经过几个测试项目了解它是如何工作的,我决定在我正在开发的汽车监视器的HomeFragment中实现它。
一切看起来都很好并且工作正常直到我移动将Home片段替换为其他片段,当我在Homefragment中返回时我得到一个错误告诉我
Attempt to invoke virtual method 'void org.rajawali3d.view.TextureView$GLThread.onResume()' on a null object reference
所以我的问题是,如何在我的Activity中管理片段内的Rajawaly TextureView?
我发现文档真的很合适,而且我也不知道GitHub所指的wiki是哪个版本的软件。是否有人设法从这个lib获得具体结果?有人知道在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();
}
OnPause:
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of FragmentHome");
rajawaliTextureView.onPause();
HandlerBinding.removeCallbacks(RunableHandlerBinding); //Some Handler
super.onPause();
}
rajawaliSurfaceView和renderer是片段中声明的两个静态istance,并在片段的onCreateView内初始化。
如果您需要更多代码,请再次提问,谢谢。
修改
我尝试使用SetPreserveEGLContextOnPause(true)来保留纹理视图,以便在片段进入onPause()时删除其内容。
它无法使其正常工作,可能是因为片段生命周期,所以我再次在此处发布我的代码
活动
这是我调用添加的代码部分替换我的Activity中的一个片段:
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);
}