mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Moved project finder logic in a separate class
- Backup before implementing Gradle Tooling API
This commit is contained in:
@@ -9,6 +9,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import com.blankj.utilcode.util.FileIOUtils;
|
||||||
import com.itsaky.androidide.EditorActivity;
|
import com.itsaky.androidide.EditorActivity;
|
||||||
import com.itsaky.androidide.adapters.ProjectsListAdapter;
|
import com.itsaky.androidide.adapters.ProjectsListAdapter;
|
||||||
import com.itsaky.androidide.app.StudioApp;
|
import com.itsaky.androidide.app.StudioApp;
|
||||||
@@ -22,12 +23,10 @@ import java.io.FileFilter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import com.blankj.utilcode.util.FileUtils;
|
import com.itsaky.androidide.project.utils.ProjectFinder;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import com.blankj.utilcode.util.FileIOUtils;
|
|
||||||
|
|
||||||
public class ProjectsFragment extends BaseFragment {
|
public class ProjectsFragment extends BaseFragment {
|
||||||
|
|
||||||
@@ -82,142 +81,15 @@ public class ProjectsFragment extends BaseFragment {
|
|||||||
mProjects = new ArrayList<>();
|
mProjects = new ArrayList<>();
|
||||||
File[] files = StudioApp.getInstance().listProjects();
|
File[] files = StudioApp.getInstance().listProjects();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
if (!file.isDirectory() || file.isHidden()) continue;
|
AndroidProject project = ProjectFinder.fromFolder(file);
|
||||||
File settings = new File(file, "settings.gradle");
|
|
||||||
if (!settings.exists()) continue;
|
if(project == null)
|
||||||
String content = FileUtil.readFile(settings.getAbsolutePath());
|
continue;
|
||||||
if (TextUtils.isEmpty(content)) continue;
|
|
||||||
AndroidProject project = new AndroidProject();
|
|
||||||
for (File module : file.listFiles()) {
|
|
||||||
if (module.isDirectory() && !module.isHidden()) {
|
|
||||||
proceedModule(file, module, project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.setAppName(file.getName());
|
|
||||||
project.setProjectPath(file.getAbsolutePath());
|
|
||||||
if(project.getMainModule() == null
|
|
||||||
&& project.getModulePaths().size() > 0
|
|
||||||
&& project.getModulePaths().get(0) != null) {
|
|
||||||
File f = new File(project.getModulePaths().get(0));
|
|
||||||
if(!f.exists() || !f.isDirectory()) continue;
|
|
||||||
project.setMainModule(f.getName());
|
|
||||||
project.setMainSourcePath(new File(f, "src/main/java").getAbsolutePath());
|
|
||||||
}
|
|
||||||
mProjects.add(project);
|
mProjects.add(project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void proceedModule(File file, File module, AndroidProject project) throws JSONException {
|
|
||||||
final Pattern appPattern = Pattern.compile("apply\\s+plugin\\s*:\\s*(\'|\")com.android.application(\'|\")");
|
|
||||||
File projectGradle = new File(file, "build.gradle");
|
|
||||||
File moduleGradle = new File(module, "build.gradle");
|
|
||||||
File manifest = new File(module, "src/main/AndroidManifest.xml");
|
|
||||||
File res = new File(module, "src/main/res");
|
|
||||||
if (!module.exists() || !projectGradle.exists() || !moduleGradle.exists() || !manifest.exists()) return;
|
|
||||||
if (!module.isDirectory() || !moduleGradle.isFile() || !projectGradle.isFile() || !manifest.isFile()) return;
|
|
||||||
|
|
||||||
File java = new File(module, "src/main/java");
|
|
||||||
if (java.exists() && java.isDirectory())
|
|
||||||
project.addSource(java.getAbsolutePath())
|
|
||||||
.addModule(module.getAbsolutePath());
|
|
||||||
|
|
||||||
File libsFolder = new File(module, "libs");
|
|
||||||
if (libsFolder.exists() && libsFolder.isDirectory()) {
|
|
||||||
File[] libs = libsFolder.listFiles();
|
|
||||||
if (libs != null && libs.length > 0) {
|
|
||||||
for (File lib : libs)
|
|
||||||
if (lib.getName().endsWith(".jar"))
|
|
||||||
project.addClasspath(lib.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.addSource(new File(module, "build/generated/source/buildConfig/debug").getAbsolutePath());
|
|
||||||
project.addSource(new File(module, "build/generated/data_binding_base_class_source_out/debug/out").getAbsolutePath());
|
|
||||||
|
|
||||||
JSONObject obj = new XmlToJson.Builder(FileUtil.readFile(manifest.getAbsolutePath())).build().toJson();
|
|
||||||
if (!obj.has("manifest")) return;
|
|
||||||
String iconPath = null;
|
|
||||||
if (obj.has("manifest") && obj.getJSONObject("manifest").has("application") && obj.getJSONObject("manifest").getJSONObject("application").has("android:icon")) {
|
|
||||||
String iconRes = obj.getJSONObject("manifest").getJSONObject("application").getString("android:icon");
|
|
||||||
if (iconRes.startsWith("@drawable")) {
|
|
||||||
final String iconName = iconRes.replace("@drawable/", "");
|
|
||||||
File[] drawables = listDrawables(res);
|
|
||||||
for (File drawable : drawables) {
|
|
||||||
File[] icons = listFilesNotEndingWith(drawable, ".xml");
|
|
||||||
for (File icon : icons) {
|
|
||||||
String nameWithoutExtension = icon.getName().substring(0, icon.getName().lastIndexOf("."));
|
|
||||||
if (nameWithoutExtension.equals(iconName)) {
|
|
||||||
iconPath = icon.getAbsolutePath();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (iconRes.startsWith("@mipmap")) {
|
|
||||||
final String iconName = iconRes.replace("@mipmap/", "");
|
|
||||||
File[] drawables = listMipmaps(res);
|
|
||||||
for (File drawable : drawables) {
|
|
||||||
File[] icons = listFilesNotEndingWith(drawable, ".xml");
|
|
||||||
for (File icon : icons) {
|
|
||||||
String nameWithoutExtension = icon.getName().substring(0, icon.getName().lastIndexOf("."));
|
|
||||||
if (nameWithoutExtension.equals(iconName)) {
|
|
||||||
iconPath = icon.getAbsolutePath();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final String packageName = obj.getJSONObject("manifest").getString("package");
|
|
||||||
final String mainModuleName = module.getName();
|
|
||||||
|
|
||||||
boolean isMainModule = false;
|
|
||||||
if(project.getMainModule() == null) {
|
|
||||||
String content = FileIOUtils.readFile2String(moduleGradle);
|
|
||||||
if(content != null && appPattern.matcher(content).find()) {
|
|
||||||
isMainModule = true;
|
|
||||||
project.setMainModule(mainModuleName);
|
|
||||||
project.setMainSourcePath(new File(module, "src/main/java").getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconPath != null) {
|
|
||||||
project.setIconPath(iconPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(packageName != null && isMainModule) {
|
|
||||||
project.setPackageName(packageName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File[] listDrawables(File file) {
|
|
||||||
return listFolderStartingWith(file, "drawable");
|
|
||||||
}
|
|
||||||
|
|
||||||
private File[] listMipmaps(File file) {
|
|
||||||
return listFolderStartingWith(file, "mipmap");
|
|
||||||
}
|
|
||||||
|
|
||||||
private File[] listFolderStartingWith(File file, final String prefix) {
|
|
||||||
return file.listFiles(new FileFilter(){
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept(File p1) {
|
|
||||||
return p1.isDirectory() && p1.getName().startsWith(prefix);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private File[] listFilesNotEndingWith(File file, final String suffix) {
|
|
||||||
return file.listFiles(new FileFilter(){
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept(File p1) {
|
|
||||||
return p1.isFile() && !p1.getName().endsWith(suffix);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProgressBar getProgressBar() {
|
public ProgressBar getProgressBar() {
|
||||||
return binding.projectsProgressBar;
|
return binding.projectsProgressBar;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
|||||||
"--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED " +
|
"--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED " +
|
||||||
"--add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED " +
|
"--add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED " +
|
||||||
"-cp $JLS_HOME/lib/jls.jar:$JLS_HOME/lib/gson.jar:$JLS_HOME/lib/protobuf.jar " +
|
"-cp $JLS_HOME/lib/jls.jar:$JLS_HOME/lib/gson.jar:$JLS_HOME/lib/protobuf.jar " +
|
||||||
"org.javacs.Main";
|
"org.javacs.Main --quiet";
|
||||||
|
|
||||||
|
|
||||||
private static final String CONTENT_LENGTH = "Content-Length: ";
|
private static final String CONTENT_LENGTH = "Content-Length: ";
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package com.itsaky.androidide.project.utils;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.blankj.utilcode.util.FileIOUtils;
|
||||||
|
import com.itsaky.androidide.models.AndroidProject;
|
||||||
|
import com.itsaky.androidide.utils.FileUtil;
|
||||||
|
import fr.arnaudguyon.xmltojsonlib.XmlToJson;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class ProjectFinder {
|
||||||
|
|
||||||
|
public static AndroidProject fromFolder(File file) {
|
||||||
|
if (!file.isDirectory() || file.isHidden()) return null;
|
||||||
|
File settings = new File(file, "settings.gradle");
|
||||||
|
if (!settings.exists()) return null;
|
||||||
|
String content = FileUtil.readFile(settings.getAbsolutePath());
|
||||||
|
if (TextUtils.isEmpty(content)) return null;
|
||||||
|
|
||||||
|
AndroidProject project = new AndroidProject();
|
||||||
|
for (File module : file.listFiles()) {
|
||||||
|
if (module.isDirectory() && !module.isHidden()) {
|
||||||
|
try {
|
||||||
|
proceedModule(file, module, project);
|
||||||
|
} catch (JSONException e) { continue; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.setAppName(file.getName());
|
||||||
|
project.setProjectPath(file.getAbsolutePath());
|
||||||
|
if(project.getMainModule() == null
|
||||||
|
&& project.getModulePaths().size() > 0
|
||||||
|
&& project.getModulePaths().get(0) != null) {
|
||||||
|
File f = new File(project.getModulePaths().get(0));
|
||||||
|
if(!f.exists() || !f.isDirectory()) return null;
|
||||||
|
project.setMainModule(f.getName());
|
||||||
|
project.setMainSourcePath(new File(f, "src/main/java").getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void proceedModule(File file, File module, AndroidProject project) throws JSONException {
|
||||||
|
final Pattern appPattern = Pattern.compile("apply\\s+plugin\\s*:\\s*(\'|\")com.android.application(\'|\")");
|
||||||
|
File projectGradle = new File(file, "build.gradle");
|
||||||
|
File moduleGradle = new File(module, "build.gradle");
|
||||||
|
File manifest = new File(module, "src/main/AndroidManifest.xml");
|
||||||
|
File res = new File(module, "src/main/res");
|
||||||
|
if (!module.exists() || !projectGradle.exists() || !moduleGradle.exists() || !manifest.exists()) return;
|
||||||
|
if (!module.isDirectory() || !moduleGradle.isFile() || !projectGradle.isFile() || !manifest.isFile()) return;
|
||||||
|
|
||||||
|
File java = new File(module, "src/main/java");
|
||||||
|
if (java.exists() && java.isDirectory())
|
||||||
|
project.addSource(java.getAbsolutePath())
|
||||||
|
.addModule(module.getAbsolutePath());
|
||||||
|
|
||||||
|
File libsFolder = new File(module, "libs");
|
||||||
|
if (libsFolder.exists() && libsFolder.isDirectory()) {
|
||||||
|
File[] libs = libsFolder.listFiles();
|
||||||
|
if (libs != null && libs.length > 0) {
|
||||||
|
for (File lib : libs)
|
||||||
|
if (lib.getName().endsWith(".jar"))
|
||||||
|
project.addClasspath(lib.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.addSource(new File(module, "build/generated/source/buildConfig/debug").getAbsolutePath());
|
||||||
|
project.addSource(new File(module, "build/generated/data_binding_base_class_source_out/debug/out").getAbsolutePath());
|
||||||
|
|
||||||
|
JSONObject obj = new XmlToJson.Builder(FileUtil.readFile(manifest.getAbsolutePath())).build().toJson();
|
||||||
|
if (!obj.has("manifest")) return;
|
||||||
|
String iconPath = null;
|
||||||
|
if (obj.has("manifest") && obj.getJSONObject("manifest").has("application") && obj.getJSONObject("manifest").getJSONObject("application").has("android:icon")) {
|
||||||
|
String iconRes = obj.getJSONObject("manifest").getJSONObject("application").getString("android:icon");
|
||||||
|
if (iconRes.startsWith("@drawable")) {
|
||||||
|
final String iconName = iconRes.replace("@drawable/", "");
|
||||||
|
File[] drawables = listDrawables(res);
|
||||||
|
for (File drawable : drawables) {
|
||||||
|
File[] icons = listFilesNotEndingWith(drawable, ".xml");
|
||||||
|
for (File icon : icons) {
|
||||||
|
String nameWithoutExtension = icon.getName().substring(0, icon.getName().lastIndexOf("."));
|
||||||
|
if (nameWithoutExtension.equals(iconName)) {
|
||||||
|
iconPath = icon.getAbsolutePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (iconRes.startsWith("@mipmap")) {
|
||||||
|
final String iconName = iconRes.replace("@mipmap/", "");
|
||||||
|
File[] drawables = listMipmaps(res);
|
||||||
|
for (File drawable : drawables) {
|
||||||
|
File[] icons = listFilesNotEndingWith(drawable, ".xml");
|
||||||
|
for (File icon : icons) {
|
||||||
|
String nameWithoutExtension = icon.getName().substring(0, icon.getName().lastIndexOf("."));
|
||||||
|
if (nameWithoutExtension.equals(iconName)) {
|
||||||
|
iconPath = icon.getAbsolutePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final String packageName = obj.getJSONObject("manifest").getString("package");
|
||||||
|
final String mainModuleName = module.getName();
|
||||||
|
|
||||||
|
boolean isMainModule = false;
|
||||||
|
if(project.getMainModule() == null) {
|
||||||
|
String content = FileIOUtils.readFile2String(moduleGradle);
|
||||||
|
if(content != null && appPattern.matcher(content).find()) {
|
||||||
|
isMainModule = true;
|
||||||
|
project.setMainModule(mainModuleName);
|
||||||
|
project.setMainSourcePath(new File(module, "src/main/java").getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconPath != null) {
|
||||||
|
project.setIconPath(iconPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packageName != null && isMainModule) {
|
||||||
|
project.setPackageName(packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File[] listDrawables(File file) {
|
||||||
|
return listFolderStartingWith(file, "drawable");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File[] listMipmaps(File file) {
|
||||||
|
return listFolderStartingWith(file, "mipmap");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File[] listFolderStartingWith(File file, final String prefix) {
|
||||||
|
return file.listFiles(new FileFilter(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File p1) {
|
||||||
|
return p1.isDirectory() && p1.getName().startsWith(prefix);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File[] listFilesNotEndingWith(File file, final String suffix) {
|
||||||
|
return file.listFiles(new FileFilter(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File p1) {
|
||||||
|
return p1.isFile() && !p1.getName().endsWith(suffix);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user