mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 15:56:48 +08:00
Merge pull request #219 from MrIkso/main
Fixed 'SuperNotCalledException' in DesignerActivity Call onDestroy in all activities removing reference to bindings Added log filter features (fixes #74).
This commit is contained in:
@@ -184,4 +184,10 @@ public class AboutActivity extends StudioActivity {
|
||||
return getString(R.string.about_footer_alternate, arch);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,4 +56,10 @@ public class CrashHandlerActivity extends StudioActivity {
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +294,7 @@ public class DesignerActivity extends StudioActivity
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
LOG.logThis();
|
||||
if (isAttrEditorShowing()) {
|
||||
getAttrEditorSheet().dismiss();
|
||||
@@ -315,8 +316,7 @@ public class DesignerActivity extends StudioActivity
|
||||
} catch (Throwable e) {
|
||||
LOG.error("Unable to release activity references from ILayoutInflater", e);
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
mBinding = null;
|
||||
}
|
||||
|
||||
private boolean isAttrEditorShowing() {
|
||||
@@ -508,4 +508,5 @@ public class DesignerActivity extends StudioActivity
|
||||
private void setDragDataToInflatedView(@NonNull IView view) {
|
||||
view.setExtraData(new WidgetDragData(true, view, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -933,7 +933,7 @@ public class EditorActivity extends StudioActivity
|
||||
initialSetup();
|
||||
setStatus(getString(R.string.msg_project_initialized));
|
||||
mBinding.buildProgressIndicator.setVisibility(View.GONE);
|
||||
|
||||
|
||||
if (mFindInProjectDialog != null && mFindInProjectDialog.isShowing()) {
|
||||
mFindInProjectDialog.dismiss();
|
||||
}
|
||||
@@ -961,8 +961,8 @@ public class EditorActivity extends StudioActivity
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
@NonNull
|
||||
public CompletableFuture<TaskExecutionResult> execTasks(
|
||||
Consumer<TaskExecutionResult> resultHandler, String... tasks) {
|
||||
saveAll(false);
|
||||
Consumer<TaskExecutionResult> resultHandler, String... tasks) {
|
||||
saveAll(false);
|
||||
runOnUiThread(() -> appendBuildOut("Executing tasks: " + TextUtils.join(", ", tasks)));
|
||||
return mBuildService
|
||||
.executeTasks(tasks)
|
||||
@@ -1348,7 +1348,8 @@ public class EditorActivity extends StudioActivity
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
final var fragment = bottomSheetTabAdapter.getFragmentAtIndex(tab.getPosition());
|
||||
if (fragment instanceof NonEditableEditorFragment) {
|
||||
if (fragment instanceof NonEditableEditorFragment
|
||||
|| fragment instanceof LogViewFragment) {
|
||||
mBinding.bottomSheet.clearFab.show();
|
||||
mBinding.bottomSheet.shareOutputFab.show();
|
||||
} else {
|
||||
@@ -1376,6 +1377,11 @@ public class EditorActivity extends StudioActivity
|
||||
if (editor.getEditor() != null) {
|
||||
editor.getEditor().setText("");
|
||||
}
|
||||
} else if (fragment instanceof LogViewFragment) {
|
||||
final var editor = (LogViewFragment) fragment;
|
||||
if (editor.getEditor() != null) {
|
||||
editor.getEditor().setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1384,19 +1390,22 @@ public class EditorActivity extends StudioActivity
|
||||
final var fragment =
|
||||
bottomSheetTabAdapter.getFragmentAtIndex(
|
||||
mBinding.bottomSheet.tabs.getSelectedTabPosition());
|
||||
if (fragment instanceof NonEditableEditorFragment) {
|
||||
final var editor = (NonEditableEditorFragment) fragment;
|
||||
if (editor.getEditor() != null) {
|
||||
final var text = editor.getEditor().getText();
|
||||
final var type =
|
||||
editor instanceof SimpleOutputFragment
|
||||
? "build_output"
|
||||
: editor instanceof IDELogFragment
|
||||
? "ide_logs"
|
||||
: editor instanceof LogViewFragment ? "app_logs" : "unknown_type";
|
||||
shareText(text, type);
|
||||
}
|
||||
CharSequence text = "";
|
||||
String type = "unknown_type";
|
||||
if (fragment instanceof SimpleOutputFragment) {
|
||||
var editor = (SimpleOutputFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "build_output";
|
||||
} else if (fragment instanceof IDELogFragment) {
|
||||
var editor = (IDELogFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "ide_logs";
|
||||
} else if (fragment instanceof LogViewFragment) {
|
||||
var editor = (IDELogFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "app_logs";
|
||||
}
|
||||
shareText(text, type);
|
||||
});
|
||||
|
||||
if (!getApp().getPrefManager().getBoolean(KEY_BOTTOM_SHEET_SHOWN)
|
||||
@@ -1520,18 +1529,14 @@ public class EditorActivity extends StudioActivity
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
final var rootProject = ProjectManager.INSTANCE.getRootProject();
|
||||
|
||||
var projectName = rootProject.getName().get();
|
||||
if(projectName.isEmpty())
|
||||
{
|
||||
projectName = new File(ProjectManager.INSTANCE.getProjectDirPath()).getName();
|
||||
getSupportActionBar()
|
||||
.setSubtitle(projectName);
|
||||
}
|
||||
else{
|
||||
getSupportActionBar()
|
||||
.setSubtitle(projectName);
|
||||
}
|
||||
|
||||
var projectName = rootProject.getName().get();
|
||||
if (projectName.isEmpty()) {
|
||||
projectName = new File(ProjectManager.INSTANCE.getProjectDirPath()).getName();
|
||||
getSupportActionBar().setSubtitle(projectName);
|
||||
} else {
|
||||
getSupportActionBar().setSubtitle(projectName);
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
// ignored
|
||||
}
|
||||
@@ -1575,7 +1580,7 @@ public class EditorActivity extends StudioActivity
|
||||
}
|
||||
|
||||
initializeLanguageServers();
|
||||
|
||||
|
||||
// Actually, we don't need to start FileOptionsHandler
|
||||
// Because it would work anyway
|
||||
// But still we do...
|
||||
|
||||
@@ -114,4 +114,10 @@ public class MainActivity extends StudioActivity {
|
||||
getApp().toast(R.string.msg_storage_denied, Toaster.Type.ERROR);
|
||||
finishAffinity();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,4 +65,10 @@ public class PreferencesActivity extends StudioActivity {
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,4 +80,10 @@ public class SplashActivity extends StudioActivity {
|
||||
mHandler.postDelayed(mRunnable, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,12 @@ public class TerminalActivity extends StudioActivity
|
||||
setTerminalCursorBlinkingState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
@@ -22,32 +22,32 @@ import androidx.annotation.NonNull;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.utils.ILogger;
|
||||
|
||||
public class IDELogFragment extends LogViewFragment {
|
||||
|
||||
private final ILogger.LogListener listener = this::log;
|
||||
|
||||
public IDELogFragment() {
|
||||
ILogger.addLogListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
return line.toSimpleString();
|
||||
}
|
||||
|
||||
private void log(int priority, String tag, @NonNull String message) {
|
||||
if (message.contains("\n")) {
|
||||
final var split = message.split("\n");
|
||||
for (var line : split) {
|
||||
logLine(priority, tag, line);
|
||||
}
|
||||
} else {
|
||||
logLine(priority, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLine(int priority, String tag, String message) {
|
||||
final var line = new LogLine(ILogger.priorityChar(priority), tag, message);
|
||||
appendLog(line);
|
||||
}
|
||||
}
|
||||
public class IDELogFragment extends LogViewFragment {
|
||||
|
||||
private final ILogger.LogListener listener = this::log;
|
||||
|
||||
public IDELogFragment() {
|
||||
ILogger.addLogListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
return line.toSimpleString();
|
||||
}
|
||||
|
||||
private void log(int priority, String tag, @NonNull String message) {
|
||||
if (message.contains("\n")) {
|
||||
final var split = message.split("\n");
|
||||
for (var line : split) {
|
||||
logLine(priority, tag, line);
|
||||
}
|
||||
} else {
|
||||
logLine(priority, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLine(int priority, String tag, String message) {
|
||||
final var line = new LogLine(ILogger.priorityChar(priority), tag, message);
|
||||
appendLog(line);
|
||||
}
|
||||
}
|
||||
@@ -18,57 +18,147 @@
|
||||
package com.itsaky.androidide.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.blankj.utilcode.util.StringUtils;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.databinding.FragmentLogViewBinding;
|
||||
import com.itsaky.androidide.language.logs.LogLanguageImpl;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
|
||||
import com.itsaky.androidide.utils.TypefaceUtils;
|
||||
import com.itsaky.androidide.views.editor.IDEEditor;
|
||||
import com.itsaky.androidide.utils.SingleTextWatcher;
|
||||
import io.github.rosemoe.sora.lang.Language;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.github.rosemoe.sora.lang.Language;
|
||||
public class LogViewFragment extends Fragment {
|
||||
|
||||
public class LogViewFragment extends NonEditableEditorFragment {
|
||||
private FragmentLogViewBinding binding;
|
||||
|
||||
private final Language language = getLanguage();
|
||||
private final List<LogLine> unsavedLines = new ArrayList<>();
|
||||
|
||||
private char priority;
|
||||
private String tag;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(
|
||||
@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = FragmentLogViewBinding.inflate(inflater, container, false);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
Objects.requireNonNull(getEditor()).setEditorLanguage(language);
|
||||
final var editor = getEditor();
|
||||
editor.setEditable(false);
|
||||
editor.setDividerWidth(0);
|
||||
editor.setWordwrap(false);
|
||||
editor.setUndoEnabled(false);
|
||||
editor.setTypefaceLineNumber(TypefaceUtils.jetbrainsMono());
|
||||
editor.setTypefaceText(TypefaceUtils.jetbrainsMono());
|
||||
editor.setTextSize(12);
|
||||
editor.setColorScheme(new SchemeAndroidIDE());
|
||||
editor.setEditorLanguage(language);
|
||||
|
||||
final var arr = requireContext().getResources().getStringArray(R.array.logcat_units);
|
||||
binding.logPrioritySpinner.setAdapter(
|
||||
new ArrayAdapter<>(
|
||||
requireContext(),
|
||||
androidx.appcompat.R.layout.support_simple_spinner_dropdown_item,
|
||||
arr));
|
||||
|
||||
binding.logPrioritySpinner.setOnItemSelectedListener(
|
||||
new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
priority = parent.getSelectedItem().toString().charAt(0);
|
||||
getEditor().setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {}
|
||||
});
|
||||
|
||||
binding
|
||||
.tagFilterInput
|
||||
.getEditText()
|
||||
.addTextChangedListener(
|
||||
new SingleTextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
tag = editable.toString();
|
||||
getEditor().setText("");
|
||||
}
|
||||
});
|
||||
|
||||
if (!unsavedLines.isEmpty()) {
|
||||
for (var line : unsavedLines) {
|
||||
applyToLanguage(line);
|
||||
getEditor().append(line.toString().trim() + "\n");
|
||||
applyToLanguage(line);
|
||||
}
|
||||
unsavedLines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filterLog(char priority, String tag, LogLine l) {
|
||||
return 'V' == priority
|
||||
|| (l.priorityChar == priority)
|
||||
&& (TextUtils.isEmpty(tag)
|
||||
|| (!TextUtils.isEmpty(tag) && (l.tag.toLowerCase().contains(tag.toLowerCase()))));
|
||||
}
|
||||
|
||||
private void applyToLanguage(LogLine line) {
|
||||
if (language instanceof LogLanguageImpl) {
|
||||
((LogLanguageImpl) this.language).addLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IDEEditor getEditor() {
|
||||
return binding.editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
public void appendLog(LogLine line) {
|
||||
if (getEditor() == null) {
|
||||
unsavedLines.add(line);
|
||||
return;
|
||||
if (filterLog(priority, tag, line)) {
|
||||
if (getEditor() == null) {
|
||||
unsavedLines.add(line);
|
||||
return;
|
||||
}
|
||||
|
||||
final var lineString = onCreateLogString(line);
|
||||
final var msg = lineString.endsWith("\n") ? lineString : lineString + "\n";
|
||||
|
||||
ThreadUtils.runOnUiThread(() -> getEditor().append(msg));
|
||||
applyToLanguage(line);
|
||||
}
|
||||
|
||||
applyToLanguage(line);
|
||||
|
||||
final var lineString = onCreateLogString(line);
|
||||
final var msg = lineString.endsWith("\n") ? lineString : lineString + "\n";
|
||||
ThreadUtils.runOnUiThread(() -> getEditor().append(msg));
|
||||
}
|
||||
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
|
||||
@@ -15,9 +15,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.transition.TransitionManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.google.android.material.transition.MaterialFadeThrough;
|
||||
import com.google.android.material.transition.MaterialSharedAxis;
|
||||
|
||||
@@ -40,6 +39,7 @@ import com.itsaky.androidide.utils.AndroidUtils;
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
import com.itsaky.androidide.utils.FileUtil;
|
||||
import com.itsaky.androidide.utils.SingleTextWatcher;
|
||||
import com.itsaky.androidide.viewmodel.WizardViewModel;
|
||||
import com.itsaky.toaster.Toaster;
|
||||
|
||||
import java.io.File;
|
||||
@@ -47,8 +47,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class WizardFragment extends BaseFragment implements ProjectWriterCallback {
|
||||
|
||||
@@ -65,6 +63,8 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
private LayoutLoadingWizardBinding loadingLayout;
|
||||
private SetupFooterBinding footerBinding;
|
||||
|
||||
private WizardViewModel mViewModel;
|
||||
|
||||
private ProgressSheet mProgressSheet;
|
||||
private ProjectTemplate mCurrentTemplate;
|
||||
private OnProjectCreatedListener mListener;
|
||||
@@ -92,6 +92,7 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
templatesBinding = binding.wizardTemplatesLayout;
|
||||
detailsBinding = binding.wizardDetailsLayout;
|
||||
footerBinding = binding.footerLayout;
|
||||
mViewModel = new ViewModelProvider(this).get(WizardViewModel.class);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@@ -106,14 +107,39 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
footerBinding.nextButton.setOnClickListener(v -> onNavigateNext());
|
||||
footerBinding.exitButton.setOnClickListener(v -> onNavigateBack());
|
||||
|
||||
loadTemplates();
|
||||
|
||||
templatesBinding.templateRecyclerview.setLayoutManager(
|
||||
new GridLayoutManager(requireContext(), 3));
|
||||
|
||||
mAdapter = new WizardTemplateAdapter();
|
||||
templatesBinding.templateRecyclerview.setAdapter(mAdapter);
|
||||
|
||||
mViewModel.createTemplatesList();
|
||||
mViewModel
|
||||
.getProjects()
|
||||
.observe(
|
||||
getViewLifecycleOwner(),
|
||||
(list) -> {
|
||||
mAdapter.submitList(list);
|
||||
});
|
||||
|
||||
mViewModel
|
||||
.getLoadingState()
|
||||
.observe(
|
||||
getViewLifecycleOwner(),
|
||||
(v) -> {
|
||||
if (v) {
|
||||
showLoading();
|
||||
} else {
|
||||
showTemplatesView();
|
||||
}
|
||||
});
|
||||
|
||||
mAdapter.setOnItemClickListener(
|
||||
(item, pos) -> {
|
||||
mCurrentTemplate = item;
|
||||
onNavigateNext();
|
||||
});
|
||||
|
||||
initDetailsView();
|
||||
}
|
||||
|
||||
@@ -126,6 +152,7 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mViewModel = null;
|
||||
binding = null;
|
||||
loadingLayout = null;
|
||||
templatesBinding = null;
|
||||
@@ -139,87 +166,11 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
return view.getAdapter().getItem(pos).toString();
|
||||
}
|
||||
|
||||
private void loadTemplates() {
|
||||
|
||||
private void showLoading() {
|
||||
TransitionManager.beginDelayedTransition((ViewGroup) requireView(), new MaterialFadeThrough());
|
||||
binding.loadingLayout.getRoot().setVisibility(View.VISIBLE);
|
||||
binding.wizardTemplatesLayout.getRoot().setVisibility(View.GONE);
|
||||
footerBinding.nextButton.setVisibility(View.GONE);
|
||||
|
||||
Executors.newSingleThreadExecutor()
|
||||
.execute(
|
||||
() -> {
|
||||
List<ProjectTemplate> templates = createTemplates();
|
||||
|
||||
if (getActivity() != null) {
|
||||
getActivity()
|
||||
.runOnUiThread(
|
||||
() -> {
|
||||
TransitionManager.beginDelayedTransition(
|
||||
(ViewGroup) requireView(), new MaterialFadeThrough());
|
||||
binding.loadingLayout.getRoot().setVisibility(View.GONE);
|
||||
binding.wizardTemplatesLayout.getRoot().setVisibility(View.VISIBLE);
|
||||
|
||||
mAdapter.submitList(templates);
|
||||
|
||||
mAdapter.setOnItemClickListener(
|
||||
(item, pos) -> {
|
||||
mCurrentTemplate = item;
|
||||
onNavigateNext();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<ProjectTemplate> createTemplates() {
|
||||
List<ProjectTemplate> mTemplates = new ArrayList<>();
|
||||
|
||||
ProjectTemplate
|
||||
empty =
|
||||
new ProjectTemplate()
|
||||
.setId(0)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(requireContext(), R.string.template_empty)
|
||||
.setDescription(requireContext(), R.string.template_description_empty)
|
||||
.setImageId(R.drawable.template_empty),
|
||||
basic =
|
||||
new ProjectTemplate()
|
||||
.setId(1)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(requireContext(), R.string.template_basic)
|
||||
.setDescription(requireContext(), R.string.template_description_basic)
|
||||
.setImageId(R.drawable.template_basic),
|
||||
drawer =
|
||||
new ProjectTemplate()
|
||||
.setId(2)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(requireContext(), R.string.template_navigation_drawer)
|
||||
.setDescription(requireContext(), R.string.template_description_navigation_drawer)
|
||||
.setImageId(R.drawable.template_navigation_drawer),
|
||||
libgdx =
|
||||
new ProjectTemplate()
|
||||
.setId(3)
|
||||
.setSupportJava(true)
|
||||
.setName(requireContext(), R.string.template_libgdx)
|
||||
.setDescription(requireContext(), R.string.template_description_libgdx)
|
||||
.setImageId(R.drawable.template_libgdx),
|
||||
compose =
|
||||
new ProjectTemplate()
|
||||
.setId(4)
|
||||
.setSupportKotlin(true)
|
||||
.setName(requireContext(), R.string.template_compose)
|
||||
.setDescription(requireContext(), R.string.template_description_compose)
|
||||
.setImageId(R.drawable.template_kotlin);
|
||||
mTemplates.add(empty);
|
||||
mTemplates.add(basic);
|
||||
mTemplates.add(drawer);
|
||||
mTemplates.add(libgdx);
|
||||
mTemplates.add(compose);
|
||||
return mTemplates;
|
||||
}
|
||||
|
||||
private int getMinSdk() {
|
||||
@@ -319,17 +270,18 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
}
|
||||
|
||||
private void showTemplatesView() {
|
||||
templatesBinding.getRoot().setVisibility(View.GONE);
|
||||
|
||||
MaterialSharedAxis sharedAxis = new MaterialSharedAxis(MaterialSharedAxis.X, false);
|
||||
|
||||
TransitionManager.beginDelayedTransition((ViewGroup) requireView(), sharedAxis);
|
||||
|
||||
binding.loadingLayout.getRoot().setVisibility(View.GONE);
|
||||
templatesBinding.getRoot().setVisibility(View.GONE);
|
||||
detailsBinding.getRoot().setVisibility(View.GONE);
|
||||
templatesBinding.getRoot().setVisibility(View.VISIBLE);
|
||||
footerBinding.nextButton.setVisibility(View.GONE);
|
||||
footerBinding.nextButton.setText(R.string.next);
|
||||
footerBinding.exitButton.setText(R.string.exit);
|
||||
binding.wizardDescriptionId.setText(R.string.new_project);
|
||||
}
|
||||
|
||||
private void showDetailsView() {
|
||||
@@ -363,7 +315,9 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
detailsBinding.etLanguage.setListSelection(0);
|
||||
detailsBinding.etLanguage.setText(getSelectedItem(0, detailsBinding.etLanguage), false);
|
||||
minSdkIndex = manager.getInt(PREF_MIN_SDK_INDEX_KEY, 5);
|
||||
targetSdkIndex = manager.getInt(PREF_TERGET_SDK_INDEX_KEY, 16);
|
||||
|
||||
// google recommended use latest target sdk version
|
||||
targetSdkIndex = manager.getInt(PREF_TERGET_SDK_INDEX_KEY, getSdks().size() - 1);
|
||||
detailsBinding.etMinSdk.setListSelection(minSdkIndex);
|
||||
detailsBinding.etMinSdk.setText(getSelectedItem(minSdkIndex, detailsBinding.etMinSdk), false);
|
||||
|
||||
@@ -382,6 +336,7 @@ public class WizardFragment extends BaseFragment implements ProjectWriterCallbac
|
||||
|
||||
detailsBinding.getRoot().setVisibility(View.VISIBLE);
|
||||
templatesBinding.getRoot().setVisibility(View.GONE);
|
||||
binding.wizardDescriptionId.setText(mCurrentTemplate.getName());
|
||||
footerBinding.nextButton.setText(R.string.create_project);
|
||||
footerBinding.nextButton.setVisibility(View.VISIBLE);
|
||||
footerBinding.exitButton.setText(R.string.previous);
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.itsaky.androidide.utils;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.itsaky.androidide.app.StudioApp;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ColorUtil {
|
||||
|
||||
public static boolean isDark(int color) {
|
||||
return ColorUtils.calculateLuminance(color) < 0.25;
|
||||
}
|
||||
|
||||
public static Object getAndroidColor(String clazz, String colorName) {
|
||||
Field declaratedField;
|
||||
try {
|
||||
declaratedField = Class.forName(clazz).getField(colorName);
|
||||
declaratedField.setAccessible(true);
|
||||
return declaratedField.get(null);
|
||||
} catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getColor(String colorValue) {
|
||||
/*
|
||||
if (colorValue.startsWith("@color/")) {
|
||||
final var resTable = StudioApp.getInstance().getResourceTable();
|
||||
String color = resTable.findColor(colorValue);
|
||||
return getColor(color);
|
||||
}
|
||||
*/
|
||||
if (colorValue.startsWith("@android:color/")) {
|
||||
Object color = getAndroidColor("android.R$color", colorValue.substring(15));
|
||||
if (color != null) {
|
||||
return StudioApp.getInstance().getColor((Integer) color);
|
||||
}
|
||||
}
|
||||
if (colorValue.startsWith("#")) {
|
||||
return Color.parseColor(colorValue);
|
||||
}
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
|
||||
public static boolean isColorValue(String value) {
|
||||
if (value.startsWith("#") | value.startsWith("@android:color") | value.startsWith("@color/")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.itsaky.androidide.viewmodel;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.blankj.utilcode.util.CollectionUtils;
|
||||
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.models.ProjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class WizardViewModel extends AndroidViewModel {
|
||||
|
||||
private MutableLiveData<List<ProjectTemplate>> mProjectTemplatesList =
|
||||
new MutableLiveData<>(CollectionUtils.newArrayList());
|
||||
private MutableLiveData<Boolean> mLoadingState = new MutableLiveData<>(true);
|
||||
|
||||
public WizardViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
public void createTemplatesList() {
|
||||
Executors.newSingleThreadExecutor()
|
||||
.execute(
|
||||
() -> {
|
||||
List<ProjectTemplate> mTemplates = new ArrayList<>();
|
||||
|
||||
ProjectTemplate
|
||||
empty =
|
||||
new ProjectTemplate()
|
||||
.setId(0)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(
|
||||
getApplication().getApplicationContext(), R.string.template_empty)
|
||||
.setDescription(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_description_empty)
|
||||
.setImageId(R.drawable.template_empty),
|
||||
basic =
|
||||
new ProjectTemplate()
|
||||
.setId(1)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(
|
||||
getApplication().getApplicationContext(), R.string.template_basic)
|
||||
.setDescription(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_description_basic)
|
||||
.setImageId(R.drawable.template_basic),
|
||||
drawer =
|
||||
new ProjectTemplate()
|
||||
.setId(2)
|
||||
.setSupportJava(true)
|
||||
.setSupportKotlin(true)
|
||||
.setName(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_navigation_drawer)
|
||||
.setDescription(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_description_navigation_drawer)
|
||||
.setImageId(R.drawable.template_navigation_drawer),
|
||||
libgdx =
|
||||
new ProjectTemplate()
|
||||
.setId(3)
|
||||
.setSupportJava(true)
|
||||
.setName(
|
||||
getApplication().getApplicationContext(), R.string.template_libgdx)
|
||||
.setDescription(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_description_libgdx)
|
||||
.setImageId(R.drawable.template_libgdx),
|
||||
compose =
|
||||
new ProjectTemplate()
|
||||
.setId(4)
|
||||
.setSupportKotlin(true)
|
||||
.setName(
|
||||
getApplication().getApplicationContext(), R.string.template_compose)
|
||||
.setDescription(
|
||||
getApplication().getApplicationContext(),
|
||||
R.string.template_description_compose)
|
||||
.setImageId(R.drawable.template_kotlin);
|
||||
|
||||
mTemplates.add(empty);
|
||||
mTemplates.add(basic);
|
||||
mTemplates.add(drawer);
|
||||
mTemplates.add(libgdx);
|
||||
mTemplates.add(compose);
|
||||
|
||||
mProjectTemplatesList.postValue(mTemplates);
|
||||
mLoadingState.postValue(false);
|
||||
});
|
||||
}
|
||||
|
||||
public LiveData<List<ProjectTemplate>> getProjects() {
|
||||
return mProjectTemplatesList;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> getLoadingState() {
|
||||
return mLoadingState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp" >
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/log_priority_spinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/logcat_units" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tag_filter_input"
|
||||
style="@style/AppTheme.TextInputLayout.Outlined"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/hint_log_tag_filter"
|
||||
app:hintEnabled="true"
|
||||
app:hintTextColor="@color/secondaryColor" >
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.itsaky.androidide.views.editor.IDEEditor
|
||||
android:id="@+id/editor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
@@ -13,8 +14,9 @@
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<string-array name="dimension_units">
|
||||
<item>dp</item>
|
||||
<item>sp</item>
|
||||
@@ -23,4 +25,14 @@
|
||||
<item>in</item>
|
||||
<item>mm</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="logcat_units">
|
||||
<item>Verbose</item>
|
||||
<item>Debug</item>
|
||||
<item>Info</item>
|
||||
<item>Warning</item>
|
||||
<item>Error</item>
|
||||
<item>Fatal</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@@ -380,6 +380,7 @@
|
||||
<string name="wizard_loading">Templates loading...</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="exit">Exit</string>
|
||||
<string name="hint_log_tag_filter">Log tags filter</string>
|
||||
|
||||
<string name="idepref_title_tpFix">JDK 11 tag pointers fix</string>
|
||||
<string name="idepref_msg_tpFix">Set LD_PRELOAD to libhook.so to fix tag pointers issue for JDK 11 in Android 11 [DEPRECATED - Prefer using JDK 17].</string>
|
||||
|
||||
@@ -1,179 +1,161 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
public class LogLine {
|
||||
|
||||
// It makes things easier in LogLanguageImpl
|
||||
public static int INFO;
|
||||
public static int DEBUG;
|
||||
public static int ERROR;
|
||||
public static int WARNING;
|
||||
|
||||
static {
|
||||
try {
|
||||
final var klass = Class.forName("com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE");
|
||||
INFO = klass.getField("LOG_INFO").getInt(null);
|
||||
DEBUG = klass.getField("LOG_DEBUG").getInt(null);
|
||||
ERROR = klass.getField("LOG_ERROR").getInt(null);
|
||||
WARNING = klass.getField("LOG_WARNING").getInt(null);
|
||||
} catch (Throwable err) {
|
||||
INFO = 0;
|
||||
DEBUG = 1;
|
||||
ERROR = 2;
|
||||
WARNING = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public String unformatted;
|
||||
public String date;
|
||||
public String time;
|
||||
public String pid;
|
||||
public String tid;
|
||||
public String tag;
|
||||
public String message;
|
||||
public char priorityChar;
|
||||
public int priority;
|
||||
public boolean formatted;
|
||||
|
||||
// For JSONRpc
|
||||
@SuppressWarnings("unused")
|
||||
private LogLine() {}
|
||||
|
||||
public LogLine(char priorityChar, String tag, String message) {
|
||||
this("", "", "", "", priorityChar, tag, message);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message) {
|
||||
this(date, time, pid, tid, priorityChar, tag, message, true);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message,
|
||||
boolean formatted) {
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.pid = pid;
|
||||
this.tid = tid;
|
||||
this.priorityChar = priorityChar;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
this.priority = parsePriority(priorityChar);
|
||||
this.formatted = formatted;
|
||||
|
||||
if (tag.length() > 25) {
|
||||
this.tag = "...".concat(tag.substring(tag.length() - 25));
|
||||
}
|
||||
}
|
||||
|
||||
private int parsePriority(char s) {
|
||||
final var c = Character.toLowerCase(s);
|
||||
if (c == 'w') {
|
||||
return WARNING;
|
||||
} else if (c == 'e') {
|
||||
return ERROR;
|
||||
} else if (c == 'i') {
|
||||
return INFO;
|
||||
} else {
|
||||
return DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public LogLine(String unformatted) {
|
||||
this.unformatted = unformatted;
|
||||
this.formatted = false;
|
||||
}
|
||||
|
||||
public static LogLine forLogString(final String log) {
|
||||
try {
|
||||
final var split = log.split("\\s", 7);
|
||||
return new LogLine(
|
||||
split[0], // date
|
||||
split[1], // time
|
||||
split[2], // process id
|
||||
split[3], // thread id
|
||||
split[4].charAt(0), // priority
|
||||
split[5], // tag
|
||||
split[6] // message
|
||||
);
|
||||
} catch (Throwable th) {
|
||||
return new LogLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
int id = 0xffffffff;
|
||||
if (priority == WARNING) {
|
||||
id = 0xffff7043;
|
||||
} else if (priority == ERROR) {
|
||||
id = 0xffc50e29;
|
||||
} else if (priority == INFO) {
|
||||
id = 0xff4caf50;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.formatted
|
||||
? String.format(
|
||||
"%-6s %-13s %-6s %-6s %-2s %-35s %s",
|
||||
date, time, pid, tid, priorityChar, trimIfNeeded(tag, 35), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
private String trimIfNeeded(String tag, int maxLength) {
|
||||
final var sb = new StringBuilder(tag);
|
||||
final var length = tag.length();
|
||||
if (length > maxLength) {
|
||||
final var start = length - maxLength;
|
||||
sb.delete(0, start);
|
||||
|
||||
// When the tag is long enough, prefix the tag with '..'
|
||||
sb.setCharAt(0, '.');
|
||||
sb.setCharAt(1, '.');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toSimpleString() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %-2s %s", trimIfNeeded(tag, 25), priorityChar, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
public String formattedTagAndMessage() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %s", trimIfNeeded(tag, 25), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
public class LogLine {
|
||||
|
||||
// It makes things easier in LogLanguageImpl
|
||||
public static int INFO;
|
||||
public static int DEBUG;
|
||||
public static int ERROR;
|
||||
public static int WARNING;
|
||||
|
||||
static {
|
||||
try {
|
||||
final var klass = Class.forName("com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE");
|
||||
INFO = klass.getField("LOG_INFO").getInt(null);
|
||||
DEBUG = klass.getField("LOG_DEBUG").getInt(null);
|
||||
ERROR = klass.getField("LOG_ERROR").getInt(null);
|
||||
WARNING = klass.getField("LOG_WARNING").getInt(null);
|
||||
} catch (Throwable err) {
|
||||
INFO = 0;
|
||||
DEBUG = 1;
|
||||
ERROR = 2;
|
||||
WARNING = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public String unformatted;
|
||||
public String date;
|
||||
public String time;
|
||||
public String pid;
|
||||
public String tid;
|
||||
public String tag;
|
||||
public String message;
|
||||
public char priorityChar;
|
||||
public int priority;
|
||||
public boolean formatted;
|
||||
|
||||
// For JSONRpc
|
||||
@SuppressWarnings("unused")
|
||||
private LogLine() {}
|
||||
|
||||
public LogLine(char priorityChar, String tag, String message) {
|
||||
this("", "", "", "", priorityChar, tag, message);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message) {
|
||||
this(date, time, pid, tid, priorityChar, tag, message, true);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message,
|
||||
boolean formatted) {
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.pid = pid;
|
||||
this.tid = tid;
|
||||
this.priorityChar = priorityChar;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
this.priority = parsePriority(priorityChar);
|
||||
this.formatted = formatted;
|
||||
}
|
||||
|
||||
private int parsePriority(char s) {
|
||||
final var c = Character.toLowerCase(s);
|
||||
if (c == 'w') {
|
||||
return WARNING;
|
||||
} else if (c == 'e') {
|
||||
return ERROR;
|
||||
} else if (c == 'i') {
|
||||
return INFO;
|
||||
} else {
|
||||
return DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public LogLine(String unformatted) {
|
||||
this.unformatted = unformatted;
|
||||
this.formatted = false;
|
||||
}
|
||||
|
||||
public static LogLine forLogString(final String log) {
|
||||
try {
|
||||
final var split = log.split("\\s", 7);
|
||||
return new LogLine(
|
||||
split[0], // date
|
||||
split[1], // time
|
||||
split[2], // process id
|
||||
split[3], // thread id
|
||||
split[4].charAt(0), // priority
|
||||
split[5], // tag
|
||||
split[6] // message
|
||||
);
|
||||
} catch (Throwable th) {
|
||||
return new LogLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.formatted
|
||||
? String.format("%s %s %s/%s %s/%s %s", date, time, pid, tid, priorityChar, tag, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
private String trimIfNeeded(String tag, int maxLength) {
|
||||
final var sb = new StringBuilder(tag);
|
||||
final var length = tag.length();
|
||||
if (length > maxLength) {
|
||||
final var start = length - maxLength;
|
||||
sb.delete(0, start);
|
||||
|
||||
// When the tag is long enough, prefix the tag with '..'
|
||||
sb.setCharAt(0, '.');
|
||||
sb.setCharAt(1, '.');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toSimpleString() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %-2s %s", trimIfNeeded(tag, 25), priorityChar, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
public String formattedTagAndMessage() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %s", trimIfNeeded(tag, 25), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user