unity打aar包工具

时间:2021-12-10 15:49:10

需求:

unity将游戏导出android工程之后,打成aar包的工具

第一种:

高版本的unity导出的android工程是android studio版的,那么打成aar的流程就是

1.build.gradle文件中把apply plugin: 'com.android.application'改成apply plugin: 'com.android.library'
2.build.gradle文件中buildToolsVersion改为25.0.2
3.注释掉applicationId这一行
4.清单文件AndroidManifest.xml中启动Activity,一般是UnityPlayerActiity,标签内全部删除
5.src.java下类UnityPlayerActiity共三个都删除
6.然后在主目录下执行命令gradlew.bat assembleDebug生成aar

把上述流程做成java自动的工具,代码如下

package com.jinkejoy.build_aar;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class ASBuildAarFile {

    private static final String CACHE_PATH = "C:\\build-apk-path.properties";
    private JFrame jFrame;

    private JTextField sourcePath_text;
    private JButton sourcePath_button;
    private File sourceFile;

    private JTextField output_text;
    private JButton output_button;
    private File outputFile;

    private JTextField sdk_text;
    private JButton sdk_button;
    private File sdkFile;

    private JTextField ndk_text;
    private JButton ndk_button;
    private File ndkFile;

    private JButton buildAar_button;
    private JButton outputAar_button;

    public static void main(String[] args) {
        new ASBuildAarFile();
    }

    public ASBuildAarFile() {
        openFileWindow();
    }

    private void openFileWindow() {
        jFrame = new JFrame();
        jFrame.setTitle("将android工程打成aar");
        jFrame.setBounds(500, 500, 700, 200);
        jFrame.setVisible(true);
        FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.LEFT);
        //选择文件
        JLabel filePath_label = new JLabel("工程路径:");
        sourcePath_text = new JTextField(50);
        sourcePath_button = new JButton("浏览");
        //输出路径
        JLabel output_label = new JLabel("出包路径:");
        output_text = new JTextField(50);
        output_button = new JButton("浏览");
        //sdk
        JLabel sdk_label = new JLabel("本地sdk路径:");
        sdk_text = new JTextField(48);
        sdk_button = new JButton("浏览");
        //ndk
        JLabel ndk_label = new JLabel("本地ndk路径(sdk路径下):");
        ndk_text = new JTextField(42);
        ndk_button = new JButton("浏览");
        //构建
        buildAar_button = new JButton("构建aar");
        outputAar_button = new JButton("弹出aar(构建aar成功后再点)");
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setLayout(layout);
        jFrame.setResizable(false);
        jFrame.add(filePath_label);
        jFrame.add(sourcePath_text);
        jFrame.add(sourcePath_button);
        jFrame.add(output_label);
        jFrame.add(output_text);
        jFrame.add(output_button);
        jFrame.add(sdk_label);
        jFrame.add(sdk_text);
        jFrame.add(sdk_button);
        jFrame.add(ndk_label);
        jFrame.add(ndk_text);
        jFrame.add(ndk_button);
        jFrame.add(buildAar_button);
        jFrame.add(outputAar_button);
        choosePath();
        outputPath();
        sdkPath();
        ndkPath();
        buildAar();
        outputAar();
        getCachePath();
    }

    public void choosePath() {
        sourcePath_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                sourceFile = chooser.getSelectedFile();
                sourcePath_text.setText(sourceFile.getAbsolutePath().toString());
            }
        });
    }

    private void outputPath() {
        output_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                outputFile = chooser.getSelectedFile();
                output_text.setText(outputFile.getAbsolutePath().toString());
            }
        });
    }

    private void sdkPath() {
        sdk_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                sdkFile = chooser.getSelectedFile();
                sdk_text.setText(sdkFile.getAbsolutePath().toString());
            }
        });
    }

    private void ndkPath() {
        ndk_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                ndkFile = chooser.getSelectedFile();
                ndk_text.setText(ndkFile.getAbsolutePath().toString());
            }
        });
    }

    private void buildAar() {
        buildAar_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                buildAarImpl();
            }
        });
    }

    private void outputAar() {
        outputAar_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                outputAarImpl(sourcePath_text.getText().toString());
            }
        });
    }

    private void cachePath() {
        String cache = "sourcePath=" + sourcePath_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "outputPath=" + output_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "sdkPath=" + sdk_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "ndkPath=" + ndk_text.getText().toString().replace("\\", "\\\\") + "\n";
        File cacheFile = new File(CACHE_PATH);
        if (!cacheFile.exists()) {
            try {
                cacheFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileOutputStream fop = new FileOutputStream(cacheFile);
            fop.write(cache.getBytes());
            fop.flush();
            fop.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getCachePath() {
        File cacheFile = new File(CACHE_PATH);
        if (cacheFile.exists()) {
            try {
                FileInputStream fip = new FileInputStream(cacheFile);
                Properties properties = new Properties();
                properties.load(fip);
                Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<Object, Object> entry = iterator.next();
                    switch (entry.getKey().toString()) {
                        case "sourcePath":
                            sourcePath_text.setText(entry.getValue().toString());
                            break;
                        case "outputPath":
                            output_text.setText(entry.getValue().toString());
                            break;
                        case "sdkPath":
                            sdk_text.setText(entry.getValue().toString());
                            break;
                        case "ndkPath":
                            ndk_text.setText(entry.getValue().toString());
                            break;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void buildAarImpl() {
        if (checkInput()) return;
        cachePath();
        String filePath = sourcePath_text.getText().toString();
        findUpdateFile(filePath);
        gradleBuildAar();
    }

    private void gradleBuildAar() {
        String command = "cmd /c start gradle clean assembleDebug";
        File cmdPath = new File(sourcePath_text.getText().toString());
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec(command, null, cmdPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void outputAarImpl(String filePath) {
        if (checkInput()) return;
        findAarFile(filePath);
        String command = "cmd /k start " + output_text.getText().toString();
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void findAarFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        File[] files = file.listFiles();
        for (File outputFile : files) {
            if (outputFile.isDirectory()) {
                findAarFile(outputFile.getAbsolutePath());
            } else {
                String fileName = outputFile.getName().toString();
                if (fileName.endsWith(".aar")) {
                    String time = timeStamp2Date(String.valueOf(System.currentTimeMillis()));
                    String aarName = fileName.substring(0, fileName.length() - 4);
                    File aarFile = new File(output_text.getText().toString() + "\\" + aarName + time + ".aar");
                    outputFile.renameTo(aarFile);
                }
            }
        }
    }

    private void findUpdateFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        File[] files = file.listFiles();
        for (File updateFile : files) {
            if (updateFile.isDirectory()) {
                findUpdateFile(updateFile.getAbsolutePath());
            } else {
                switch (updateFile.getName().toString()) {
                    case "build.gradle":
                        updateBuildGradle(updateFile.getAbsolutePath());
                        break;
                    case "AndroidManifest.xml":
                        updateManifestFile(updateFile.getAbsolutePath());
                        break;
                    case "local.properties":
                        updateSdkFile(updateFile.getAbsolutePath());
                        break;
                    case "UnityPlayerActivity.java":
                    case "UnityPlayerNativeActivity.java":
                    case "UnityPlayerProxyActivity.java":
                        updateFile.delete();
                        break;
                }
            }
        }
    }

    private void updateSdkFile(String filePath) {
        try {
            RandomAccessFile sdkFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = sdkFile.readLine()) != null) {
                final long point = sdkFile.getFilePointer();
                if (line.contains("sdk.dir")) {
                    String s = line.substring(0);
                    String sdkStr = sdk_text.getText().toString();
                    String sdkPan = sdkStr.substring(0, 1);
                    sdkStr = sdkStr.substring(1).replace("\\", "\\\\");
                    String ndkStr = ndk_text.getText().toString();
                    String ndkPan = ndkStr.substring(0, 1);
                    ndkStr = ndkStr.substring(1).replace("\\", "\\\\");
                    String replaceStr = "sdk.dir=" + sdkPan + "\\" + sdkStr + "\n" + "ndk.dir=" + ndkPan + "\\" + ndkStr + "\n                      ";
                    String str = line.replace(s, replaceStr);
                    sdkFile.seek(lastPoint);
                    sdkFile.writeBytes(str);
                }
                lastPoint = point;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void updateManifestFile(String filePath) {
        try {
            RandomAccessFile manifestFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = manifestFile.readLine()) != null) {
                final long ponit = manifestFile.getFilePointer();
                if (line.contains("<activity") && line.contains("UnityPlayerActivity") && !line.contains("<!--<activity")) {
                    String str = line.replace("<activity", "<!--<activity");
                    manifestFile.seek(lastPoint);
                    manifestFile.writeBytes(str);
                }
                if (line.contains("</activity>") && !line.contains("</activity>-->")) {
                    String str = line.replace("</activity>", "</activity>-->\n");
                    manifestFile.seek(lastPoint);
                    manifestFile.writeBytes(str);
                }
                lastPoint = ponit;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void updateBuildGradle(String filePath) {
        try {
            RandomAccessFile buildGradleFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = buildGradleFile.readLine()) != null) {
                final long ponit = buildGradleFile.getFilePointer();
                if (line.contains("classpath 'com.android.tools.build:gradle")) {
                    String s = line.substring(line.indexOf("classpath"));
                    String str = line.replace(s, "classpath 'com.android.tools.build:gradle:2.3.0'\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("com.android.application")) {
                    String str = line.replace("'com.android.application'", "'com.android.library'    \n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("compileSdkVersion") && !line.contains("compileSdkVersion 25")) {
                    String s = line.substring(line.indexOf("compileSdkVersion")).toString();
                    String str = line.replace(s, "compileSdkVersion 25\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("buildToolsVersion") && !line.contains("buildToolsVersion '25.0.2'")) {
                    String s = line.substring(line.indexOf("buildToolsVersion")).toString();
                    String str = line.replace(s, "buildToolsVersion '25.0.2'\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("targetSdkVersion") && !line.contains("targetSdkVersion 25")) {
                    String s = line.substring(line.indexOf("targetSdkVersion")).toString();
                    String str = line.replace(s, "targetSdkVersion 25\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("applicationId") && !line.contains("//applicationId")) {
                    String s = line.substring(line.indexOf("applicationId")).toString();
                    String str = line.replace(s, "//" + s + "\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                lastPoint = ponit;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean checkInput() {
        if ("".equals(sourcePath_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入源工程文件路径");
            return true;
        }
        if ("".equals(output_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入apk输出路径");
            return true;
        }
        if ("".equals(sdk_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入本地sdk路径");
            return true;
        }
        if ("".equals(ndk_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入本地ndk路径");
            return true;
        }
        return false;
    }

    public static String timeStamp2Date(String time) {
        Long timeLong = Long.parseLong(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(timeLong));
            return sdf.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}

方法名写的很清楚,我就不加注释了。

jar包打成可运行程序参考android studio打可执行jar包

效果图

unity打aar包工具

第二种:

低版本的unity导出的android工程是Eclipse版的

Eclipse版的android工程和android studio版的android工程还是有不小区别的,

android studio版unity打aar包工具eclipse版unity打aar包工具

所以我增加了一个母包,用于把eclipse版变成android studio版,代码如下

package com.jinkejoy.build_aar;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class EcBuildAarFile {

    private static final String CACHE_PATH = "C:\\build-apk-path.properties";
    private JFrame jFrame;

    private JTextField sourcePath_text;
    private JButton sourcePath_button;
    private File sourceFile;

    private JTextField output_text;
    private JButton output_button;
    private File outputFile;

    private JTextField sdk_text;
    private JButton sdk_button;
    private File sdkFile;

    private JTextField ndk_text;
    private JButton ndk_button;
    private File ndkFile;

    private JTextField main_text;
    private JButton main_button;
    private File mainFile;

    private JButton buildAar_button;
    private JButton outputAar_button;

    public static void main(String[] args) {
        new EcBuildAarFile();
    }

    public EcBuildAarFile() {
        openFileWindow();
    }

    private void openFileWindow() {
        jFrame = new JFrame();
        jFrame.setTitle("将android工程打成aar");
        jFrame.setBounds(500, 500, 700, 250);
        jFrame.setVisible(true);
        FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.LEFT);
        //选择文件
        JLabel filePath_label = new JLabel("工程路径:");
        sourcePath_text = new JTextField(50);
        sourcePath_button = new JButton("浏览");
        //输出路径
        JLabel output_label = new JLabel("出包路径:");
        output_text = new JTextField(50);
        output_button = new JButton("浏览");
        //sdk
        JLabel sdk_label = new JLabel("本地sdk路径:");
        sdk_text = new JTextField(48);
        sdk_button = new JButton("浏览");
        //ndk
        JLabel ndk_label = new JLabel("本地ndk路径(sdk路径下):");
        ndk_text = new JTextField(42);
        ndk_button = new JButton("浏览");
        //母包
        JLabel main_label = new JLabel("本地母包文件路径:");
        main_text = new JTextField(45);
        main_button = new JButton("浏览");
        //构建
        buildAar_button = new JButton("构建aar");
        outputAar_button = new JButton("弹出aar(构建aar成功后再点)");
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setLayout(layout);
        jFrame.setResizable(false);
        jFrame.add(filePath_label);
        jFrame.add(sourcePath_text);
        jFrame.add(sourcePath_button);
        jFrame.add(output_label);
        jFrame.add(output_text);
        jFrame.add(output_button);
        jFrame.add(sdk_label);
        jFrame.add(sdk_text);
        jFrame.add(sdk_button);
        jFrame.add(ndk_label);
        jFrame.add(ndk_text);
        jFrame.add(ndk_button);
        jFrame.add(main_label);
        jFrame.add(main_text);
        jFrame.add(main_button);
        jFrame.add(buildAar_button);
        jFrame.add(outputAar_button);
        choosePath();
        outputPath();
        sdkPath();
        ndkPath();
        mainPath();
        buildAar();
        outputAar();
        getCachePath();
    }

    public void choosePath() {
        sourcePath_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                sourceFile = chooser.getSelectedFile();
                sourcePath_text.setText(sourceFile.getAbsolutePath().toString());
            }
        });
    }

    private void outputPath() {
        output_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                outputFile = chooser.getSelectedFile();
                output_text.setText(outputFile.getAbsolutePath().toString());
            }
        });
    }

    private void sdkPath() {
        sdk_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                sdkFile = chooser.getSelectedFile();
                sdk_text.setText(sdkFile.getAbsolutePath().toString());
            }
        });
    }

    private void ndkPath() {
        ndk_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                ndkFile = chooser.getSelectedFile();
                ndk_text.setText(ndkFile.getAbsolutePath().toString());
            }
        });
    }

    private void mainPath() {
        main_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.showDialog(new JLabel(), "选择");
                mainFile = chooser.getSelectedFile();
                main_text.setText(mainFile.getAbsolutePath().toString());
            }
        });
    }

    private void buildAar() {
        buildAar_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                buildAarImpl();
            }
        });
    }

    private void outputAar() {
        outputAar_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                outputAarImpl(main_text.getText().toString());
            }
        });
    }

    private void cachePath() {
        String cache = "sourcePath=" + sourcePath_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "outputPath=" + output_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "sdkPath=" + sdk_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "ndkPath=" + ndk_text.getText().toString().replace("\\", "\\\\") + "\n" +
                "mainPath=" + main_text.getText().toString().replace("\\", "\\\\");
        File cacheFile = new File(CACHE_PATH);
        if (!cacheFile.exists()) {
            try {
                cacheFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileOutputStream fop = new FileOutputStream(cacheFile);
            fop.write(cache.getBytes());
            fop.flush();
            fop.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getCachePath() {
        File cacheFile = new File(CACHE_PATH);
        if (cacheFile.exists()) {
            try {
                FileInputStream fip = new FileInputStream(cacheFile);
                Properties properties = new Properties();
                properties.load(fip);
                Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<Object, Object> entry = iterator.next();
                    switch (entry.getKey().toString()) {
                        case "sourcePath":
                            sourcePath_text.setText(entry.getValue().toString());
                            break;
                        case "outputPath":
                            output_text.setText(entry.getValue().toString());
                            break;
                        case "sdkPath":
                            sdk_text.setText(entry.getValue().toString());
                            break;
                        case "ndkPath":
                            ndk_text.setText(entry.getValue().toString());
                            break;
                        case "mainPath":
                            main_text.setText(entry.getValue().toString());
                            break;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void buildAarImpl() {
        if (checkInput()) return;
        cachePath();
        createAs();
        findUpdateFile(main_text.getText().toString());
        gradleBuildAar();
    }

    private void createAs() {
        String sourcePath = sourcePath_text.getText().toString();
        String mainPath = main_text.getText().toString();
        //delete history
        String deletePath = mainPath + "\\app\\src\\main";
        delAllFile(deletePath);
        String buildPath1 = mainPath + "\\build";
        delFolder(buildPath1);
        String buildPath2 = mainPath + "\\app\\build";
        delFolder(buildPath2);
        //assets
        String assets = sourcePath + "\\assets";
        String newAssets = mainPath + "\\app\\src\\main\\assets";
        copyFolder(assets, newAssets);
        //unity-classes.jar
        String unity = sourcePath + "\\libs\\unity-classes.jar";
        String newUnity = mainPath + "\\app\\libs\\unity-classes.jar";
        copyFile(new File(unity), new File(newUnity));
        //libs
        String libs = sourcePath + "\\libs";
        String jniLibs = mainPath + "\\app\\src\\main\\jniLibs";
        copyFolder(libs, jniLibs);
        File jni_unity = new File(jniLibs + "\\unity-classes.jar");
        jni_unity.delete();
        //res
        String res = sourcePath + "\\res";
        String newRes = mainPath + "\\app\\src\\main\\res";
        copyFolder(res, newRes);
        //src
        String src = sourcePath + "\\src";
        String java = mainPath + "\\app\\src\\main\\java";
        copyFolder(src, java);
        //AndroidManifest.xml
        String manifest = sourcePath + "\\AndroidManifest.xml";
        String newManifest = mainPath + "\\app\\src\\main\\AndroidManifest.xml";
        copyFile(new File(manifest), new File(newManifest));
    }

    public boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);//再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    public void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); //删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void copyFile(File source, File dest) {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(dest).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void copyFolder(String oldPath, String newPath) {
        try {
            // 如果文件夹不存在,则建立新文件夹
            (new File(newPath)).mkdirs();
            // 读取整个文件夹的内容到file字符串数组,下面设置一个游标i,不停地向下移开始读这个数组
            File filelist = new File(oldPath);
            String[] file = filelist.list();
            // 要注意,这个temp仅仅是一个临时文件指针
            // 整个程序并没有创建临时文件
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                // 如果oldPath以路径分隔符/或者\结尾,那么则oldPath/文件名就可以了
                // 否则要自己oldPath后面补个路径分隔符再加文件名
                // 谁知道你传递过来的参数是f:/a还是f:/a/啊?
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                // 如果游标遇到文件
                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    // 复制并且改名
                    FileOutputStream output = new FileOutputStream(newPath
                            + "/" + (temp.getName()).toString());
                    byte[] bufferarray = new byte[1024 * 64];
                    int prereadlength;
                    while ((prereadlength = input.read(bufferarray)) != -1) {
                        output.write(bufferarray, 0, prereadlength);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                // 如果游标遇到文件夹
                if (temp.isDirectory()) {
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            System.out.println("复制整个文件夹内容操作出错");
        }
    }

    private void gradleBuildAar() {
        String command = "cmd /c start gradle clean assembleDebug";
        File cmdPath = new File(main_text.getText().toString());
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec(command, null, cmdPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void outputAarImpl(String filePath) {
        if (checkInput()) return;
        findAarFile(filePath);
        String command = "cmd /k start " + output_text.getText().toString();
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void findAarFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        File[] files = file.listFiles();
        for (File outputFile : files) {
            if (outputFile.isDirectory()) {
                findAarFile(outputFile.getAbsolutePath());
            } else {
                String fileName = outputFile.getName().toString();
                if (fileName.endsWith(".aar")) {
                    String time = timeStamp2Date(String.valueOf(System.currentTimeMillis()));
                    String aarName = fileName.substring(0, fileName.length() - 4);
                    File aarFile = new File(output_text.getText().toString() + "\\" + aarName + time + ".aar");
                    outputFile.renameTo(aarFile);
                }
            }
        }
    }

    private void findUpdateFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        File[] files = file.listFiles();
        for (File updateFile : files) {
            if (updateFile.isDirectory()) {
                findUpdateFile(updateFile.getAbsolutePath());
            } else {
                switch (updateFile.getName().toString()) {
                    case "build.gradle":
                        updateBuildGradle(updateFile.getAbsolutePath());
                        break;
                    case "AndroidManifest.xml":
                        updateManifestFile(updateFile.getAbsolutePath());
                        break;
                    case "local.properties":
                        updateSdkFile(updateFile.getAbsolutePath());
                        break;
                    case "UnityPlayerActivity.java":
                    case "UnityPlayerNativeActivity.java":
                    case "UnityPlayerProxyActivity.java":
                        updateFile.delete();
                        break;
                }
            }
        }
    }

    private void updateSdkFile(String filePath) {
        try {
            RandomAccessFile sdkFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = sdkFile.readLine()) != null) {
                final long point = sdkFile.getFilePointer();
                if (line.contains("sdk.dir")) {
                    String s = line.substring(0);
                    String sdkStr = sdk_text.getText().toString();
                    String sdkPan = sdkStr.substring(0, 1);
                    sdkStr = sdkStr.substring(1).replace("\\", "\\\\");
                    String ndkStr = ndk_text.getText().toString();
                    String ndkPan = ndkStr.substring(0, 1);
                    ndkStr = ndkStr.substring(1).replace("\\", "\\\\");
                    String replaceStr = "sdk.dir=" + sdkPan + "\\" + sdkStr + "\n" + "ndk.dir=" + ndkPan + "\\" + ndkStr + "\n                      ";
                    String str = line.replace(s, replaceStr);
                    sdkFile.seek(lastPoint);
                    sdkFile.writeBytes(str);
                }
                lastPoint = point;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void updateManifestFile(String filePath) {
        try {
            RandomAccessFile manifestFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = manifestFile.readLine()) != null) {
                final long ponit = manifestFile.getFilePointer();
                if (line.contains("<activity") && line.contains("UnityPlayerActivity") && !line.contains("<!--<activity")) {
                    String str = line.replace("<activity", "<!--<activity");
                    manifestFile.seek(lastPoint);
                    manifestFile.writeBytes(str);
                }
                if (line.contains("</activity>") && !line.contains("</activity>-->")) {
                    String str = line.replace("</activity>", "</activity>-->\n");
                    manifestFile.seek(lastPoint);
                    manifestFile.writeBytes(str);
                }
                lastPoint = ponit;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void updateBuildGradle(String filePath) {
        try {
            RandomAccessFile buildGradleFile = new RandomAccessFile(filePath, "rw");
            String line;
            long lastPoint = 0;
            while ((line = buildGradleFile.readLine()) != null) {
                final long ponit = buildGradleFile.getFilePointer();
                if (line.contains("classpath 'com.android.tools.build:gradle")) {
                    String s = line.substring(line.indexOf("classpath"));
                    String str = line.replace(s, "classpath 'com.android.tools.build:gradle:2.3.0'  \n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("com.android.application")) {
                    String str = line.replace("'com.android.application'", "'com.android.library'    \n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("compileSdkVersion") && !line.contains("compileSdkVersion 25")) {
                    String s = line.substring(line.indexOf("compileSdkVersion")).toString();
                    String str = line.replace(s, "compileSdkVersion 25\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("buildToolsVersion") && !line.contains("buildToolsVersion '25.0.2'")) {
                    String s = line.substring(line.indexOf("buildToolsVersion")).toString();
                    String str = line.replace(s, "buildToolsVersion '25.0.2'\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("targetSdkVersion") && !line.contains("targetSdkVersion 25")) {
                    String s = line.substring(line.indexOf("targetSdkVersion")).toString();
                    String str = line.replace(s, "targetSdkVersion 25\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                if (line.contains("applicationId") && !line.contains("//applicationId")) {
                    String s = line.substring(line.indexOf("applicationId")).toString();
                    String str = line.replace(s, "//" + s + "\n");
                    buildGradleFile.seek(lastPoint);
                    buildGradleFile.writeBytes(str);
                }
                lastPoint = ponit;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean checkInput() {
        if ("".equals(sourcePath_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入源工程文件路径");
            return true;
        }
        if ("".equals(output_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入apk输出路径");
            return true;
        }
        if ("".equals(sdk_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入本地sdk路径");
            return true;
        }
        if ("".equals(ndk_text.getText().toString())) {
            JOptionPane.showMessageDialog(jFrame, "请输入本地ndk路径");
            return true;
        }
        return false;
    }

    public static String timeStamp2Date(String time) {
        Long timeLong = Long.parseLong(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(timeLong));
            return sdf.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}

效果图

unity打aar包工具