java - Android - dlopen 失败 : file offset for the library

标签 java android

我正在为我的 arduino 汽车制作一个远程控制应用程序。所使用的代码首先使用 Java 在 Eclipse 中进行了测试,现在我尝试对 Android 应用程序使用相同的代码。

我使用了jSerialComm库,根据Android Studio我的代码没有错误,但是当我运行它时,它找不到该库?我收到以下错误:

FATAL EXCEPTION: main Process: com.sahragard.avengrecontroller, PID: 11728 java.lang.UnsatisfiedLinkError: dlopen failed: file offset for the library "/data/user/0/com.sahragard.avengrecontroller/cache/1454627726168-libjSerialComm.so"

= file size: 0 >= 0 at java.lang.Runtime.load(Runtime.java:332) at java.lang.System.load(System.java:1069) at com.fazecast.jSerialComm.SerialPort.(SerialPort.java:181) at com.sahragard.avengrecontroller.Conn.getPorts(Conn.java:19) at com.sahragard.avengrecontroller.MainActivity.onCreate(MainActivity.java:25) at android.app.Activity.performCreate(Activity.java:6237) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我在谷歌上搜索了很多小时,并按照我找到的提示进行操作,但无论我做什么,总是出现同样的错误。我已经根据这篇文章添加了库: https://stackoverflow.com/a/16628496/4582696

非常感谢我能得到的任何帮助!提前致谢。

编辑:

MainActivity类是对包含Swing接口(interface)的类的改编,其代码添加在这段代码下面

public class MainActivity extends AppCompatActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Spinner conSpinner =(Spinner) findViewById(R.id.spinner);

        String[] a = new String[Conn.getPorts().length];
        for(int i=0; i<Conn.getPorts().length; i++){
            a[i] = Conn.getPorts()[i].getSystemPortName();
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, a);
        conSpinner.setAdapter(adapter);


        final Button disconnectButton = (Button) findViewById(R.id.disconnect);
        disconnectButton.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.disconnect();
            }
        });


        final Button connectButton = (Button) findViewById(R.id.connect);
        connectButton.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.connect(conSpinner.getSelectedItemPosition());
                Runnable run = new Runnable() {
                    public void run() {
                        Conn.listen();
                    }
                };
                Conn.listen = new Thread(run);
                Conn.listen.start();
            }
        });



        final Button up = (Button) findViewById(R.id.upButton);
        up.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.sendMsg("w");
            }
        });

        final Button down = (Button) findViewById(R.id.downButton);
        down.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.sendMsg("s");
            }
        });

        final Button left = (Button) findViewById(R.id.leftButton);
        left.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.sendMsg("a");
            }
        });

        final Button right = (Button) findViewById(R.id.rightButton);
        right.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                Conn.sendMsg("d");
            }
        });




    }
}

原始Remote_Interface类

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.fazecast.jSerialComm.SerialPort;

import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextPane;
import java.awt.SystemColor;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Remote_Interface extends JFrame {

    private JPanel contentPane;
    private JTextField textField;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Remote_Interface frame = new Remote_Interface();
                    frame.setVisible(true);
//                  Conn.listen();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Remote_Interface() {
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 270, 268);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JComboBox<String> comboBox = new JComboBox<String> ();
        comboBox.setBounds(20, 46, 214, 20);
        for(int i=0; i<Conn.getPorts().length; i++){
            comboBox.addItem(Conn.getPorts()[i].getSystemPortName());
        }
        contentPane.add(comboBox);

        textField = new JTextField();
        textField.setBounds(20, 131, 214, 20);
        contentPane.add(textField);
        textField.setColumns(10);

        textField.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                Conn.sendMsg(e.getActionCommand());
                textField.setText("");
            }
        });

        JButton btnNewButton = new JButton("Send");
        btnNewButton.setBounds(20, 162, 89, 23);
        contentPane.add(btnNewButton);

        JTextPane txtpnPleaseSelectA = new JTextPane();
        txtpnPleaseSelectA.setBackground(SystemColor.control);
        txtpnPleaseSelectA.setText("Please select a port to connect");
        txtpnPleaseSelectA.setEditable(false);
        txtpnPleaseSelectA.setBounds(10, 11, 214, 20);
        contentPane.add(txtpnPleaseSelectA);

        btnNewButton.setEnabled(false);
        textField.setEnabled(false);

        JButton btnNewButton_1 = new JButton("Connect");
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Conn.connect(comboBox.getSelectedIndex());
                btnNewButton.setEnabled(true);
                textField.setEnabled(true);
                Runnable run = new Runnable(){
                    public void run(){
                        Conn.listen();
                    }
                };
                Conn.listen = new Thread(run);
                Conn.listen.start();
            }
        });
        btnNewButton_1.setBounds(143, 77, 89, 23);
        contentPane.add(btnNewButton_1);

        JButton btnD = new JButton("Disconnect");
        btnD.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Conn.disconnect();
                btnNewButton.setEnabled(false);
                textField.setEnabled(false);
            }
        });
        btnD.setBounds(20, 77, 89, 23);
        contentPane.add(btnD);
    }
}

还有康恩级

import com.fazecast.jSerialComm.*;

import java.io.PrintWriter;
import java.util.Scanner;

public class Conn {

static  PrintWriter out;
static  SerialPort[] ports;
static  SerialPort port;
static  Scanner in;
static Thread listen;

public static SerialPort[] getPorts(){
    ports = SerialPort.getCommPorts();
    return ports;
}

public static void sendMsg(String s){
    out.println(s);
    out.flush();
}

public static void connect(int i){
    port = ports[i];
    port.openPort();
    port.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
    out = new PrintWriter(port.getOutputStream());
    in = new Scanner(port.getInputStream());
}

public static void disconnect(){
    port.closePort();

}

public static void listen(){// handle the input from the Arduino chip 
    while(in.hasNextLine()){
        System.out.println(in.nextLine());// just print it out to the console 
    }
}



}

最佳答案

我遇到了同样的问题,解决这个问题的唯一方法是:

  1. https://github.com/Fazecast/jSerialComm/tree/master/src/main/java/com/fazecast/jSerialComm 复制文件进入我的项目,保持与原始包名称相同的包名称。
  2. https://mvnrepository.com/artifact/com.fazecast/jSerialComm/1.3.11 下载 jar 并解压它,复制\jSerialComm-1.3.11\Android\内的所有文件夹
  3. 粘贴项目 src/main/jniLibs 中的所有文件夹
  4. 调用System.loadLibrary("jSerialComm");在进行任何方法调用之前。

之后

SerialPort myPort = SerialPort.getCommPort("/dev/ttyMT2");

给出了相应的对象,没有任何UnsatisfiedLinkError。

*另一件事,如果您使用/dev 文件夹,则可能需要进行 Android 构建,其中 SeLinux 权限模式设置为“Disabled”或“Permissive”。 https://www.centos.org/docs/5/html/5.1/Deployment_Guide/sec-sel-enable-disable.html

关于java - Android - dlopen 失败 : file offset for the library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213730/

相关文章:

java - 和 children 一起阅读 POM

android - 使用 Google Maps Android API v2 时出错

java - 管理单个 Clicklistener 的 Libgdx 问题

java - 错误 "Attempt to invoke virtual method ' 双 java.lang.Double.doubleValue( )' on a null object reference"

java - java中使用可重入锁进行锁定同步

java - if-else 语句和运算符的问题

android - Android OpenCV 端口有什么缺点吗?

java - 使用 List<type> 而不是 ArrayList<Hashmap<String,String>> 进行 ListView

java - 如何将地理距离过滤器与 boolean 术语查询合并

java - 来自子查询的 SQLite : How to populate a boolean field on a pojo,