在线打包app是指用户可以在网页上上传自己的应用程序并自动打包生成apk安装文件。这样的应用程序在一些应用商店已经很常见,比如pgyer、fir.im等。本文将介绍一套可供参考的在线打包app的源码实现方法。
首先,我们需要一个服务器端。服务器端需要提供以下功能:
1. 支持用户上传apk文件,并存储在服务器端。
2. 支持用户在网页上对apk文件进行打包。打包的过程需要将apk文件复制到一个新的文件夹中,并对新的文件夹进行签名和打包。
3. 支持用户下载生成的apk文件。下载的地址一般是在文件存储目录下的一个访问地址。
下面是一个简单的服务器端实现示例(使用node.js):
```javascript
// 引入依赖
var express = require('express');
var formidable = require('formidable');
var fs = require('fs');
var path = require('path');
var child_process = require('child_process');
// 创建express应用
var app = express();
// 设置静态文件目录
app.use(express.static('public'));
// POST /upload 接口,用于上传apk文件
app.post('/upload', function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
var file = files.file;
var uploadPath = path.join(__dirname, 'uploads', file.name);
// 保存上传的文件
fs.rename(file.path, uploadPath, function() {
res.send({ code: 0, file: uploadPath });
});
});
});
// POST /pack 接口,用于打包apk
app.post('/pack', function(req, res) {
var outputPath = path.join(__dirname, 'output');
var inputPath = req.body.file;
var apkName = path.basename(inputPath);
var apkPath = path.join(outputPath, apkName);
// 复制apk文件到打包目录
fs.copyFileSync(inputPath, apkPath);
// 切换工作目录到打包目录
process.chdir(outputPath);
// 执行打包命令
child_process.exec('jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore release.keystore -keypass 123456 -storepass 123456 ' +
apkName + ' alias_name', function(err, stdout, stderr) {
if (err) {
console.log(stderr);
res.send({ code: -1 });
return;
}
child_process.exec('zipalign -v 4 ' + apkName + ' app.apk', function(err, stdout, stderr) {
if (err) {
console.log(stderr);
res.send({ code: -1 });
return;
}
res.send({ code: 0, url: '/apk/' + apkName });
});
});
});
// 监听3000端口
app.listen(3000, function() {
console.log('app is running at port 3000');
});
```
以上代码实现了上传和打包两个接口。上传接口使用了node.js中的formidable中间件处理文件上传逻辑。打包接口使用了Child Process模块来执行签名和打包命令。
接下来,我们需要一个客户端页面。
首先,我们需要一个input元素来支持文件上传:
```html
```
其中,上传按钮需要在选择好文件后变为可用状态,可以使用change事件监听文件选择的动作:
```javascript
var fileInput = document.getElementById('file-input');
var uploadBtn = document.getElementById('upload-btn');
fileInput.addEventListener('change', function(ev) {
var file = ev.target.files[0];
if (file) {
uploadBtn.disabled = false;
} else {
uploadBtn.disabled = true;
}
});
```
接下来,我们需要将文件上传到服务器端。使用XMLHttpRequest或fetch来实现:
```javascript
// 上传文件
function upload(file) {
var formData = new FormData();
formData.append('file', file);
return fetch('/upload', {
method: 'POST',
body: formData,
}).then(function(response) {
return response.json();
});
}
// 上传按钮的click事件
uploadBtn.addEventListener('click', function() {
var file = fileInput.files[0];
upload(file).then(function(result) {
if (result.code === 0) {
packBtn.disabled = false;
packBtn.dataset.file = result.file;
} else {
alert('上传失败');
}
});
});
```
上传成功后,我们需要执行打包操作。打包操作需要调用/pack接口,并下载最终生成的apk文件:
```javascript
// 打包按钮的click事件
packBtn.addEventListener('click', function() {
var file = packBtn.dataset.file;
pack(file).then(function(result) {
if (result.code === 0) {
window.location = result.url;
} else {
alert('打包失败');
}
});
});
// 执行打包操作
function pack(file) {
var formData = new FormData();
formData.append('file', file);
return fetch('/pack', {
method: 'POST',
body: formData,
}).then(function(response) {
return response.json();
});
}
```
最终的生成apk文件的地址会存储在result.url字段中。
这就是一个简单的在线打包app的实现方法。放到生产环境中还需要继续完善代码逻辑和安全性。