APPH5+APP版本自动更新的实现代码
这个问题的代码实现因为方案不同而不同,下面提供两个实现方案:
方案一:使用第三方库
可以使用第三方库,例如jAutoUpdate,它可以帮助我们自动更新应用程序。这个库支持Java Web Start、Swing、JavaFX和Android等多种平台的自动更新。
以下是使用jAutoUpdate自动更新的示例代码:
import de.schlichtherle.util.*;
import de.schlichtherle.util.zip.*;
import de.schlichtherle.xml.*;
import de.schlichtherle.xml.GenericDescriptor.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import org.apache.commons.codec.binary.*;
import org.apache.commons.io.*;
import org.apache.commons.lang3.*;
import org.apache.commons.lang3.exception.*;
import org.dom4j.*;
import org.dom4j.io.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import org.xml.sax.*;
public class AutoUpdater {
private static final String UPDATE_URL = "http://www.example.com/update.xml";
private static final String APP_PATH = ".";
private static final String APP_FILE = "myapp.jar";
private static final String APP_CLASS_NAME = "com.example.Main";
private static final String UPDATE_FILE = "update.zip";
private static final String UPDATE_DESC_FILE = "update.xml";
private static final String UPDATE_INFO_FILE = "update_info.xml";
private static final String UPDATE_CHECK_FILE = "update_check.xml";
private static final String UPDATE_TEMP_PATH = System.getProperty("java.io.tmpdir") + "myapp_update/";
public static void main(String[] args) {
try {
String version = getVersion();
String updateCheckUrl = UPDATE_URL + "?" + UUID.randomUUID().toString();
File updateCheckFile = getFile(UPDATE_TEMP_PATH + UPDATE_CHECK_FILE);
FileUtils.copyURLToFile(new URL(updateCheckUrl), updateCheckFile);
String updateVersion = getUpdateVersion(updateCheckFile);
if (StringUtils.isNotEmpty(updateVersion) && !version.equals(updateVersion)) {
downloadUpdate(updateCheckFile);
String updateFilePath = UPDATE_TEMP_PATH + UPDATE_FILE;
File updateFile = getFile(updateFilePath);
unzipUpdate(updateFilePath, UPDATE_TEMP_PATH);
String updateDescFilePath = UPDATE_TEMP_PATH + UPDATE_DESC_FILE;
GenericDescriptor updateDesc = getUpdateDesc(updateDescFilePath);
updateApp(updateFile, updateDesc);
JOptionPane.showMessageDialog(null, "The application has been updated. Please restart the application.");
System.exit(0);
} else {
Class.forName(APP_CLASS_NAME).getMethod("main", String[].class).invoke(null, (Object) args);
}
} catch (Throwable t) {
t.printStackTrace();
String message = ExceptionUtils.getStackTrace(t);
JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE);
}
}
private static String getVersion() throws Exception {
String appFilePath = APP_PATH + "/" + APP_FILE;
Manifest manifest = new JarFile(appFilePath).getManifest();
String version = manifest.getMainAttributes().getValue("Implementation-Version");
return version;
}
private static String getUpdateVersion(File updateCheckFile) throws Exception {
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(updateCheckFile);
Element root = document.getRootElement();
String updateVersion = root.getChildText("version");
return updateVersion;
}
private static void downloadUpdate(File updateCheckFile) throws Exception {
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(updateCheckFile);
Element root = document.getRootElement();
String updateUrl = root.getChildText("url");
String updateFilePath = UPDATE_TEMP_PATH + UPDATE_FILE;
FileUtils.copyURLToFile(new URL(updateUrl), getFile(updateFilePath));
}
private static void unzipUpdate(String updateFilePath, String updateTempPath) throws Exception {
ZipFile zipFile = new ZipFile(updateFilePath);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entry.isDirectory()) {
getFile(updateTempPath + entryName).mkdirs();
} else {
InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream outputStream = new FileOutputStream(getFile(updateTempPath + entryName));
IOUtils.copy(inputStream, outputStream);
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}
}
}
private static GenericDescriptor getUpdateDesc(String updateDescFilePath) throws Exception {
FileInputStream inputStream = new FileInputStream(getFile(updateDescFilePath));
InputSource inputSource = new InputSource(inputStream);
GenericDescriptor updateDesc = new GenericDescriptor();
updateDesc.read(inputSource);
IOUtils.closeQuietly(inputStream);
return updateDesc;
}
private static void updateApp(File updateFile, GenericDescriptor updateDesc) throws Exception {
String appFilePath = APP_PATH + "/" + APP_FILE;
String backupFilePath = APP_PATH + "/" + APP_FILE + ".bak";
FileUtils.copyFile(new File(appFilePath), new File(backupFilePath));
FileUtils.copyFile(updateFile, new File(appFilePath));
updateDesc.write(new FileOutputStream(APP_PATH + "/META-INF/update.xml"), "UTF-8");
}
private static File getFile(String path) throws Exception {
File file = new File(path);
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
}
需要注意的是,上述代码假设更新文件是一个zip压缩包,其中包含一个update.xml文件和一个更新的应用程序文件。update.xml文件包含了更新的描述信息,例如版本号、更新的URL等。更新的应用程序文件是一个jar文件,可以包含多个类和资源文件。
方案二:手动实现
手动实现应用程序自动更新的过程需要以下步骤:
- 获取当前应用程序的版本号。
- 向服务器请求更新信息的URL。
- 解析服务器返回的更新信息,获取最新版本号和更新的URL等信息。
- 如果最新版本号大于当前版本号,则下载更新文件。
- 解压更新文件。
- 备份旧的应用程序文件。
- 将更新的应用程序文件复制到应用程序目录下。
- 重启应用程序。
以下是手动实现自动更新的示例代码:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;
import javax.swing.*;
public class AutoUpdater {
private static final String UPDATE_URL = "http://www.example.com/update.xml";
private static final String APP_PATH = ".";
private static final String APP_FILE = "myapp.jar";
private static final String APP_CLASS_NAME = "com.example.Main";
private static final String UPDATE_FILE = "update.zip";
private static final String UPDATE_TEMP_PATH = System.getProperty("java.io.tmpdir") + "myapp_update/";
public static void main(String[] args) {
try {
String version = getVersion();
String updateCheckUrl = UPDATE_URL + "?" + UUID.randomUUID().toString();
String updateCheckResult = downloadUpdateCheck(updateCheckUrl);
String updateVersion = getUpdateVersion(updateCheckResult);
if (updateVersion != null && compareVersion(updateVersion, version) > 0) {
String updateUrl = getUpdateUrl(updateCheckResult);
downloadUpdate(updateUrl);
String updateFilePath = UPDATE_TEMP_PATH + UPDATE_FILE;
unzipUpdate(updateFilePath, UPDATE_TEMP_PATH);
backupApp();
updateApp(updateFilePath);
JOptionPane.showMessageDialog(null, "The application has been updated. Please restart the application.");
System.exit(0);
} else {
Class.forName(APP_CLASS_NAME).getMethod("main", String[].class).invoke(null, (Object) args);
}
} catch (Throwable t) {
t.printStackTrace();
String message = t.getMessage();
JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE);
}
}
private static String getVersion() throws Exception {
String appFilePath = APP_PATH + "/" + APP_FILE;
Manifest manifest = new JarFile(appFilePath).getManifest();
String version = manifest.getMainAttributes().getValue("Implementation-Version");
return version;
}
private static String downloadUpdateCheck(String updateCheckUrl) throws Exception {
HttpURLConnection connection = (HttpURLConnection) new URL(updateCheckUrl).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
InputStream inputStream = connection.getInputStream();
String result = readStream(inputStream);
inputStream.close();
connection.disconnect();
return result;
}
private static String readStream(InputStream inputStream) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
String result = new String(outputStream.toByteArray(), "UTF-8");
outputStream.close();
return result;
}
private static String getUpdateVersion(String updateCheckResult) throws Exception {
int index = updateCheckResult.indexOf("<version>");
if (index != -1) {
int endIndex = updateCheckResult.indexOf("</version>", index);
if (endIndex != -1) {
String version = updateCheckResult.substring(index + "<version>".length(), endIndex);
return version;
}
}
return null;
}
private static String getUpdateUrl(String updateCheckResult) throws Exception {
int index = updateCheckResult.indexOf("<url>");
if (index != -1) {
int endIndex = updateCheckResult.indexOf("</url>", index);
if (endIndex != -1) {
String url = updateCheckResult.substring(index + "<url>".length(), endIndex);
return url;
}
}
return null;
}
private static int compareVersion(String version1, String version2) {
String[] v1 = version1.split("\\.");
String[] v2 = version2.split("\\.");
int length = Math.max(v1.length, v2.length);
for (int i = 0; i < length; i++) {
int n1 = i < v1.length ? Integer.parseInt(v1[i]) : 0;
int n2 = i < v2.length ? Integer.parseInt(v2[i]) : 0;
if (n1 != n2) {
return n1 > n2 ? 1 : -1;
}
}
return 0;
}
private static void downloadUpdate(String updateUrl) throws Exception {
HttpURLConnection connection = (HttpURLConnection) new URL(updateUrl).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(getFile(UPDATE_TEMP_PATH + UPDATE_FILE));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
connection.disconnect();
}
private static void unzipUpdate(String updateFilePath, String updateTempPath) throws Exception {
ZipFile zipFile = new ZipFile(updateFilePath);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entry.isDirectory()) {
getFile(updateTempPath + entryName).mkdirs();
} else {
InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream outputStream = new FileOutputStream(getFile(updateTempPath + entryName));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
}
zipFile.close();
}
private static void backupApp() throws Exception {
String appFilePath = APP_PATH + "/" + APP_FILE;
String backupFilePath = APP_PATH + "/" + APP_FILE + ".bak";
FileUtils.copyFile(new File(appFilePath), new File(backupFilePath));
}
private static void updateApp(String updateFilePath) throws Exception {
String appFilePath = APP_PATH + "/" + APP_FILE;
File appFile = new File(appFilePath);
appFile.delete();
FileUtils.copyFile(new File(updateFilePath), appFile);
}
private static File getFile(String path) throws Exception {
File file = new File(path);
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
}
需要注意的是,上述代码假设更新文件是一个zip压缩包,其中包含一个更新的应用程序文件。更新的应用程序文件是一个jar文件,可以包含多个类和资源文件。更新信息使用XML格式保存,例如:
<update>
<version>1.1.0</version>
<url>http://www.example.com/myapp_1.1.0.jar</url>
</update>
原文地址: https://www.cveoy.top/t/topic/bS9Q 著作权归作者所有。请勿转载和采集!