简体   繁体   English

如何在不同的线程上访问 android 应用程序的资产? (爪哇)

[英]How to access android app's assets on a different thread? (Java)

This is a reformulation of my question here: How to access files form the Renderer class Opengles (android, java) ,but nobody answered, so I decided to ask in a different way.这是我在这里的问题的重新表述: How to access files form the Renderer class Opengles (android, java) ,但没有人回答,所以我决定以不同的方式提问。

I am building an Opengl es app for android and I want to access some local files.我正在为 android 构建一个 Opengl es 应用程序,我想访问一些本地文件。 My main game loop is situated in the Renderer class which is an implementation of GLSurfaceView.Renderer and will be used to set the view in the MainActivity.我的主游戏循环位于渲染器 class 中,它是 GLSurfaceView.Renderer 的实现,将用于在 MainActivity 中设置视图。 The only way I know of getting kind of local files* is to do Activity.getAssets().open("file.something");我知道获取本地文件*的唯一方法是执行 Activity.getAssets().open("file.something"); but then I need the MainActivity.但后来我需要 MainActivity。 The problem is, if I understood my researches correctly, the Renderer class is automaticaly run on a seperate thread than MainActivity, which results in MainActivity.getAssets().open();问题是,如果我正确理解了我的研究,渲染器 class 会自动在与 MainActivity 不同的线程上运行,这会导致 MainActivity.getAssets().open(); to return nothing.什么都不返回。 Please help me find a workaround or just use threads, if thats the solution.如果那是解决方案,请帮助我找到解决方法或仅使用线程。

*I know that they are not called local files, but they still serve the purpose of beeing files that you don't access with an absolute path qnd that's what I want. *我知道它们不被称为本地文件,但它们仍然用于处理您无法使用绝对路径访问的文件 qnd 这就是我想要的。

Edit #1:编辑#1:

Here's where I call getAssets.open():这里是我调用 getAssets.open() 的地方:

import android.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.widget.Toast;
import com.GyooStudios.Glu.MainActivity;
import com.GyooStudios.Glu.ShaderProgram;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;


public abstract class ShaderProgram {
  
  private int programID;
  private int vertexShaderID;
  private int fragmentShaderID;
  
  public boolean hasFoundFile = true;
  public boolean isCompiled = true;
  public boolean canReadFile = true;
  
  public String exceptionError = "null";
  
  public ShaderProgram (MainActivity main, String vertexFile, String fragmentFile){
    vertexShaderID = loadShader(main, vertexFile, GLES20.GL_VERTEX_SHADER);
    fragmentShaderID = loadShader(main, fragmentFile, GLES20.GL_FRAGMENT_SHADER);
    
    programID = GLES20.glCreateProgram();
    GLES20.glAttachShader(programID, vertexShaderID);
    GLES20.glAttachShader(programID, fragmentShaderID);
    GLES20.glLinkProgram(programID);
    GLES20.glValidateProgram(programID);
  }
  
  public void start(){
    GLES20.glUseProgram(programID);
  }
  
  public void stop(){
    GLES20.glUseProgram(0);
  }
  
  protected abstract void bindAttributes();
  
  protected void bindAttribute(int attribute, String variableName){
    GLES20.glBindAttribLocation(programID, attribute, variableName);
  }
  
  private int loadShader(MainActivity main,String fileName, int type){
    int shaderID = 0;
    try{
      InputStream file = main.getAssets().open(fileName);
      Scanner scan = new Scanner(file);
      String code = new String();
      while(scan.hasNext()){
        code = new String(code + scan.nextLine() + "/n");
      }
      
      shaderID = GLES20.glCreateShader(type);
      GLES20.glShaderSource(shaderID, code);
      GLES20.glCompileShader(shaderID);
      int[] compileStatus = new int[1];
      GLES20.glGetShaderiv(shaderID,GLES20.GL_COMPILE_STATUS,compileStatus,0);
      if(compileStatus[0] == 0){
        Toast.makeText(main.getApplicationContext(),GLES20.glGetShaderInfoLog(shaderID),Toast.LENGTH_LONG);
        GLES20.glDeleteShader(shaderID);
        isCompiled = false;
      }
    }catch(FileNotFoundException e){
      hasFoundFile = false;
    }catch(IOException e){
      canReadFile = false;
    }catch(Exception e){
      isCompiled = false;
      exceptionError = "something went wrong";
      exceptionError = e.toString();
    }
    
    return shaderID;
    
  }
}

ShaderProgram is Implemented in this class: ShaderProgram在这个class中实现:

import com.GyooStudios.Glu.MainActivity;


public class StaticShader extends ShaderProgram{
  
  private static final String VERTEX_FILE = "quad.vertex";
  private static final String FRAGMENT_FILE = "quad.fragment";
  
  public StaticShader(MainActivity main){
    super(main,VERTEX_FILE, FRAGMENT_FILE);
    //bindAttributes();
  }
  
  @Override
  protected void bindAttributes(){
    super.bindAttribute(0,"position");
  }
  
}

StaticShader is used in the constructor of another class which is created in Renederer. StaticShader 用于另一个 class 的构造函数中,该 class 是在 Renederer 中创建的。 Renderer is beeing used here, in MainActivity:在 MainActivity 中使用了渲染器:

import android.Manifest;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.widget.Toast;
import com.GyooStudios.Glu.StaticShader;
import com.GyooStudios.Glu.renderer;
import java.io.InputStream;
import java.util.Scanner;

public class MainActivity extends Activity {
    
    private renderer surface;
    private GLSurfaceView surfaceView;
    private int STORAGE_PERMISSION_CODE = 1;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Keep in mind that renderer implements GLSurfaceView.Renderer
        //And yes, renderer class is with a lower case r, it's my mistake.
        super.onCreate(savedInstanceState);
        surfaceView = new GLSurfaceView(this);
        surfaceView.setEGLContextClientVersion(2);
        surface = new renderer(this);
        surfaceView.setRenderer(surface);
        setContentView(surfaceView);
    }
    
    protected void onPause(){
        super.onPause();
        surfaceView.onPause();
    }
    
    protected void onResume(){
        super.onResume();
        surfaceView.onResume();
    }

}

Edit #2: I tried passing only the AssetManager returned by Activity.getAssets();编辑#2:我尝试只传递 Activity.getAssets(); 返回的 AssetManager; and also the Context.还有上下文。 The AssetManager lets the apps run, but it gives me an Exception and I couldn't figure which one. AssetManager 让应用程序运行,但它给了我一个异常,我不知道是哪一个。 When I tired to get the exception using Toast.makeText(passedOnContext,exception.toString(),Toast.LENGTH_LONG);当我厌倦了使用 Toast.makeText(passedOnContext,exception.toString(),Toast.LENGTH_LONG); it crashed the app.它使应用程序崩溃。 (And yes I use Toasts to get debug messages, it's limitation of my IDE, it doesn't provide a terminal in apps developpement) (是的,我使用 Toasts 来获取调试消息,这是我的 IDE 的限制,它在应用程序开发中不提供终端)

Turns out that wasn't the problem at all: See here to get the new problem: GLES20.glShaderSource does nothing事实证明这根本不是问题:请参阅此处以获取新问题: GLES20.glShaderSource 什么都不做

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何访问我的Android应用中的资产文件夹? - How to access assets folder in my android app? 如何从另一个线程访问线程的对象-Java - How to access a thread's object from another thread - Java 我可以从另一个线程访问 Java 中另一个线程的资源吗? - Can I access another thread's resources in Java from a different thread? 如何在Java / Android中的AsyncTask中访问其他URL - How to access different URL in AsyncTask in Java/Android 被Android访问控制机制所迷惑。 与Java不同 - Confused by Android access control mechanism. It's DIFFERENT from java Android / Java:如何调用在不同线程上创建的对象的方法? - Android/Java: How to call methods of an object created on a different thread? 如何*确切*从 Android Java *Plugin* 平台代码中访问 Flutter 资产? - How *Exactly* to Access Flutter Assets From Within Android Java *Plugin* Platform Code? 在Android项目中访问资产文件夹的方式是什么? - What's the way to access the assets-folder in an Android project? 通过Android应用中的fileinputstream(string fileName)访问Assets文件夹中的文件 - Access file in assets folder via fileinputstream(string fileName) in android app 如何通过Android中的线程从资产中获取XML文件? - How to get a XML file from assets via a thread in Android?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM