LoginSignup
0
1

More than 5 years have passed since last update.

androidのjava(processing)からnode.jsを動かす

Last updated at Posted at 2018-11-23

はじめに

皆様はandroidでjava以外を動かした事がありますか?
動かすだけならtermuxや言語ごとのアプリを使えば出来ることが多いですがapkに詰めて配布するのは難しいです(pythonについては挫折しました)
しかしながら今回紹介するNode.jsの様に先人の知恵によりandroidで動かす為の道がある程度敷かれているものもあります
ということで前置きはここまでにして実際にやり方を見ていきましょう

必要なもの

node in android
androidでjavaを動かす環境

準備

assetsに必要なものを入れていきましょう
とりあえずnpmは要らないので
assets/resource/binにダウンロードしたnodeというファイルを入れてください
WriteExternalStorageのpermissionまたはreadExternalStorageのpermissionを適宜追加してください

import

最初に

import java.io.IOException;
import java.util.Map;
import fi.iki.elonen.*;
import android.content.res.AssetManager;
import android.os.Bundle;
import java.io.*;
import java.util.*;

をimportしておいてください

assetsからlocalStorageへのコピーする関数

localStorageにあるファイルしか実行できないのでcopyFiles関数でassetsから移します

private boolean isDirectory(final String path) throws IOException { 
  AssetManager assetManager = getActivity().getResources().getAssets();
  boolean isDirectory = false;
  try {
    if (assetManager.list(path).length > 0) {
      isDirectory = true;
    } else {
      assetManager.open(path);
    }
  }
  catch (FileNotFoundException fnfe) {
    isDirectory = true;
  }
  return isDirectory;
}
private void copyFiles(final String parentPath, final String filename, final File toDir) throws IOException {
  AssetManager assetManager = getActivity().getResources().getAssets();
  String assetpath = (parentPath != null ? parentPath + File.separator + filename : filename);
  if (isDirectory(assetpath)) {
    if (!toDir.exists()) {
      toDir.mkdirs();
    } 
    for (String child : assetManager.list(assetpath)) {
      copyFiles(assetpath, child, new File(toDir, child));
    }
  } else {
    copyData(assetManager.open(assetpath), new FileOutputStream(new File(toDir.getParentFile(), filename)));
  }
}
private void copyData(InputStream input, FileOutputStream output) throws IOException {
  int DEFAULT_BUFFER_SIZE = 1024 * 4;   
  byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];    
  int n = 0;        
  while (-1 != (n = input.read(buffer))) { 
    output.write(buffer, 0, n);
  }         
  output.close();       
  input.close();
}

getContext(),getActivity()の部分は適当なものに変えてください

node.jsを呼び出す関数

adbCommandExe関数でnode.jsを呼びます
sketchPath関数はlocalstorageの位置を返します
addEnv関数は環境変数を追加します

String sketchPath(String path){
  return getContext().getFilesDir().getAbsolutePath()+"/"+path;
}
void addEnv(ProcessBuilder pb,String e,String value){
  Map<String, String> env = pb.environment();
  env.put(e,value);
}
private String adbCommandExe(String command,File dir) {
  StringBuilder suilder = new StringBuilder();
  ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
  if(dir!=null)processBuilder.directory(dir);
  addEnv(processBuilder,"LD_LIBRARY_PATH",sketchPath("lib"));
  addEnv(processBuilder,"PATH",sketchPath("bin"));
  addEnv(processBuilder,"LANG","en_US.UTF-8");
  InputStream iStream = null;
  InputStreamReader isReader = null;
  try {
    Process proc = processBuilder.start();
    iStream = proc.getInputStream();
    isReader = new InputStreamReader(iStream);
    BufferedReader bufferedReader = new BufferedReader(isReader);
    String line;
    while ((line = bufferedReader.readLine()) != null) {
      suilder.append(line);
      suilder.append("\n");
      println(line);
    }
    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 
    while ((line = br.readLine()) != null) { 
      suilder.append(line);
      suilder.append("\n");
      println(line);
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  } 
  finally {
    try {
      if (iStream != null) {
        iStream.close();
      }
      if (isReader != null) {
        isReader.close();
      }
    } 
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  return suilder.toString();
}

実行

関数を実際に呼び出します

void run(){
  try {
    copyFiles(null, "resource", new File(sketchPath("")));
  } 
  catch (IOException ioe) { 
    println("copy error");
  }
  for(File file:new File(sketchPath("bin")).listFiles()){
    if (file.setExecutable(true, true))println("a");
  }
  for(File file:new File(sketchPath("lib")).listFiles()){
    if (file.setExecutable(true, true))println("a");
  }
  File dir = new File("/storage/emulated/0/webIDE/temp");
  adbCommandExe("node -v",dir);
}

全部まとめると

node.jsを実行したい時にrun関数を呼んでみてください

void run(){
  try {
    copyFiles(null, "resource", new File(sketchPath("")));
  } 
  catch (IOException ioe) { 
    println("copy error");
  }
  for(File file:new File(sketchPath("bin")).listFiles()){
    if (file.setExecutable(true, true))println("a");
  }
  for(File file:new File(sketchPath("lib")).listFiles()){
    if (file.setExecutable(true, true))println("a");
  }
  File dir = new File("/storage/emulated/0/webIDE/temp");
  adbCommandExe("node -v",dir);
}
String sketchPath(String path){
  return getContext().getFilesDir().getAbsolutePath()+"/"+path;
}
void addEnv(ProcessBuilder pb,String e,String value){
  Map<String, String> env = pb.environment();
  env.put(e,value);
}
private String adbCommandExe(String command,File dir) {
  StringBuilder suilder = new StringBuilder();
  ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
  if(dir!=null)processBuilder.directory(dir);
  addEnv(processBuilder,"LD_LIBRARY_PATH",sketchPath("lib"));
  addEnv(processBuilder,"PATH",sketchPath("bin"));
  addEnv(processBuilder,"LANG","en_US.UTF-8");
  InputStream iStream = null;
  InputStreamReader isReader = null;
  try {
    Process proc = processBuilder.start();
    iStream = proc.getInputStream();
    isReader = new InputStreamReader(iStream);
    BufferedReader bufferedReader = new BufferedReader(isReader);
    String line;
    while ((line = bufferedReader.readLine()) != null) {
      suilder.append(line);
      suilder.append("\n");
      println(line);
    }
    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 
    while ((line = br.readLine()) != null) { 
      suilder.append(line);
      suilder.append("\n");
      println(line);
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  } 
  finally {
    try {
      if (iStream != null) {
        iStream.close();
      }
      if (isReader != null) {
        isReader.close();
      }
    } 
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  return suilder.toString();
}
private boolean isDirectory(final String path) throws IOException { 
  AssetManager assetManager = getActivity().getResources().getAssets();
  boolean isDirectory = false;
  try {
    if (assetManager.list(path).length > 0) {
      isDirectory = true;
    } else {
      assetManager.open(path);
    }
  }
  catch (FileNotFoundException fnfe) {
    isDirectory = true;
  }
  return isDirectory;
}
private void copyFiles(final String parentPath, final String filename, final File toDir) throws IOException {
  AssetManager assetManager = getActivity().getResources().getAssets();
  String assetpath = (parentPath != null ? parentPath + File.separator + filename : filename);
  if (isDirectory(assetpath)) {
    if (!toDir.exists()) {
      toDir.mkdirs();
    } 
    for (String child : assetManager.list(assetpath)) {
      copyFiles(assetpath, child, new File(toDir, child));
    }
  } else {
    copyData(assetManager.open(assetpath), new FileOutputStream(new File(toDir.getParentFile(), filename)));
  }
}
private void copyData(InputStream input, FileOutputStream output) throws IOException {
  int DEFAULT_BUFFER_SIZE = 1024 * 4;   
  byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];    
  int n = 0;        
  while (-1 != (n = input.read(buffer))) { 
    output.write(buffer, 0, n);
  }         
  output.close();       
  input.close();
}

あとがき

androidのjava(processing)からnode.jsを動かすの解説は以上となります
できましたでしょうか

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1