我的服务器上保存了一个g3db模型文件(例如http://website.com/model.g3db)。我想将该模型加载到我的Android应用程序中。
我在我的启动器类中尝试过asyncTask,首先在本地下载文件,然后使用下载的文件加载模型。但它没有用。
AndroidLauncher.java
public class AndroidLauncher extends AndroidApplication {
public final static String FILENAME = "model";
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
private LinearLayout modelView;
private Viewer viewer; // Viewer Class
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewer);
modelView = (LinearLayout) findViewById(R.id.view);
startDownload();
}
private void startDownload() {
String url = "http://website.com/model.g3db";
new DownloadFileAsync().execute(url);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
file = new File(getFilesDir(), FILENAME);
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = openFileOutput(FILENAME, Context.MODE_PRIVATE);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Toast.makeText(AndroidLauncher.this, "File Writing Problem", Toast.LENGTH_LONG).show();
}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
// Now Initialize Viewer class as we have the model downloaded locally
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useGLSurfaceView20API18 = true;
viewer = new Viewer();
modelView.addView(initializeForView(viewer, config));
}
}
Viewer.java
private FileHandle fileHandle;
private ModelLoader modelLoader;
@Override
public void create () {
stage = new Stage();
font = new BitmapFont();
label = new Label(" ", new Label.LabelStyle(font, Color.WHITE));
stage.addActor(label);
stringBuilder = new StringBuilder();
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(10,21,0);
cam.lookAt(0,0,0);
cam.up.set(Vector3.Y);
cam.near = 5;
cam.far = 70;
cam.update();
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(new InputMultiplexer(this, camController));
// Locally Stored Model File -----
handle = Gdx.files.local("model.g3db");
UBJsonReader jsonReader = new UBJsonReader();
modelLoader = new G3dModelLoader(jsonReader);
loading = true;
}
private void doneLoading () {
Model model = modelLoader.loadModel(fileHandle);
for (int i = 0; i < model.nodes.size; i++) {
String id = model.nodes.get(i).id;
GameObject instance = new GameObject(model, id, true);
instances.add(instance);
}
loading = false;
}
但是当我运行应用程序时出现错误
java.lang.RuntimeException: Unable to resume activity {in.SpaceFix.SpaceFix.android/in.SpaceFix.SpaceFix.android.AndroidLauncher}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.badlogic.gdx.backends.android.AndroidInput.onResume()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3137)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5530)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.badlogic.gdx.backends.android.AndroidInput.onResume()' on a null object reference
at com.badlogic.gdx.backends.android.AndroidApplication.onResume(AndroidApplication.java:293)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1246)
at android.app.Activity.performResume(Activity.java:6052)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3122)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5530)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
请帮助!
答案 0 :(得分:2)
看起来你推迟创建你的ApplicationListener
,它不会工作。 AndroidApplication
期望有效ApplicationListener
。使其看起来像this:
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useGLSurfaceView20API18 = true;
viewer = new Viewer();
modelView.addView(initializeForView(viewer, config));
}
另外,你应该use an interface to use platform specific code。但是,如果你真的想走上你走的路,那么你可以告诉你的观众你已经完成了下载:
viewer.downloadComplete();
在Viewer
课程中,您可以在该方法中下载需要执行的特定代码:
public void downloadComplete()
{
handle = Gdx.files.local("model.g3db");
UBJsonReader jsonReader = new UBJsonReader();
modelLoader = new G3dModelLoader(jsonReader);
Model model = modelLoader.loadModel(fileHandle);
for (int i = 0; i < model.nodes.size; i++) {
String id = model.nodes.get(i).id;
GameObject instance = new GameObject(model, id, true);
instances.add(instance);
}
}
顺便说一句,看起来您使用AssetManager
获取了my tutorial的代码并对其进行了修改,使其无法理解。您应该使用AssetManager
或不需要loading
和doneLoading()
机制。
也就是说,应该注意的是,下载文件不是特定于平台的功能,因此可以在ApplicationListener
内完成。有关更多信息,请查看HttpRequest课程。这看起来像这样:
Model model;
@Override
public void create () {
stage = new Stage();
font = new BitmapFont();
label = new Label(" ", new Label.LabelStyle(font, Color.WHITE));
stage.addActor(label);
stringBuilder = new StringBuilder();
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(10,21,0);
cam.lookAt(0,0,0);
cam.up.set(Vector3.Y);
cam.near = 5;
cam.far = 70;
cam.update();
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(new InputMultiplexer(this, camController));
Net.HttpRequest request = new Net.HttpRequest(Net.HttpMethods.GET);
request.setUrl("http://website.com/model.g3db");
Gdx.net.sendHttpRequest(request, new HttpResponseListener() {
@Override
public void handleHttpResponse (HttpResponse httpResponse) {
final FileHandle tmpFile = FileHandle.tempFile("model");
tmpFile.write(httpResponse.getResultAsStream(), false);
Gdx.app.postRunnable(new Runnable() {
@Override
public void run () {
model = new G3dModelLoader(new UBJsonReader()).loadModel(tmpFile);
for (int i = 0; i < model.nodes.size; i++) {
String id = model.nodes.get(i).id;
GameObject instance = new GameObject(model, id, true);
instances.add(instance);
}
}
});
}
@Override
public void failed (Throwable t) {
Gdx.app.error("Test", "something went wrong", t);
}
@Override
public void cancelled () {
Gdx.app.log("Test", "cancelled");
}
});
}
虽然与您的问题无关,但请注意Model
需要处理。您正在Model
方法中创建新的doneLoading()
,但从不处理它。您可能希望重新考虑您的方法,因为它会导致资源泄漏。