mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 01:48:18 +00:00
add support for loading filtered androidx libraries for code completion
This commit is contained in:
@@ -33,7 +33,8 @@ async function createLanguageClient(context) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const appSourceRoot = vscode.workspace.getConfiguration('android-dev-ext').get('appSourceRoot', '');
|
const config = vscode.workspace.getConfiguration('android-dev-ext');
|
||||||
|
const appSourceRoot = config.get('appSourceRoot', '');
|
||||||
let globSearchRoot = appSourceRoot;
|
let globSearchRoot = appSourceRoot;
|
||||||
if (globSearchRoot) {
|
if (globSearchRoot) {
|
||||||
// for findFiles to work properly, the path cannot begin with slash or have any relative components
|
// for findFiles to work properly, the path cannot begin with slash or have any relative components
|
||||||
@@ -52,7 +53,7 @@ async function createLanguageClient(context) {
|
|||||||
initializationOptions: {
|
initializationOptions: {
|
||||||
// extensionPath points to the root of the extension (the folder where this file is)
|
// extensionPath points to the root of the extension (the folder where this file is)
|
||||||
extensionPath: context.extensionPath,
|
extensionPath: context.extensionPath,
|
||||||
appSourceRoot,
|
initialSettings: config,
|
||||||
sourceFiles,
|
sourceFiles,
|
||||||
workspaceFolders: (vscode.workspace.workspaceFolders || []).map(z => z.uri.toString()),
|
workspaceFolders: (vscode.workspace.workspaceFolders || []).map(z => z.uri.toString()),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -317,6 +317,10 @@ function initDefaultCompletionTypes(lib) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearDefaultCompletionEntries() {
|
||||||
|
defaultCompletionTypes = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the VSCode completion item request.
|
* Called from the VSCode completion item request.
|
||||||
*
|
*
|
||||||
@@ -331,8 +335,10 @@ async function getCompletionItems(params, liveParsers, androidLibrary) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dct = defaultCompletionTypes;
|
||||||
if (!defaultCompletionTypes) {
|
if (!defaultCompletionTypes) {
|
||||||
initDefaultCompletionTypes(androidLibrary);
|
initDefaultCompletionTypes(androidLibrary);
|
||||||
|
dct = defaultCompletionTypes || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for the Android library to load (in case we receive an early request)
|
// wait for the Android library to load (in case we receive an early request)
|
||||||
@@ -366,7 +372,7 @@ async function getCompletionItems(params, liveParsers, androidLibrary) {
|
|||||||
lastCompletionTypeMap = (parsed && parsed.typemap) || androidLibrary;
|
lastCompletionTypeMap = (parsed && parsed.typemap) || androidLibrary;
|
||||||
|
|
||||||
let locals = [],
|
let locals = [],
|
||||||
modifiers = defaultCompletionTypes.modifiers,
|
modifiers = dct.modifiers,
|
||||||
sourceTypes = [];
|
sourceTypes = [];
|
||||||
|
|
||||||
if (parsed.unit) {
|
if (parsed.unit) {
|
||||||
@@ -404,7 +410,7 @@ async function getCompletionItems(params, liveParsers, androidLibrary) {
|
|||||||
|
|
||||||
// if this is not a static method, include this/super
|
// if this is not a static method, include this/super
|
||||||
if (!options.method.modifiers.includes('static')) {
|
if (!options.method.modifiers.includes('static')) {
|
||||||
locals.push(...defaultCompletionTypes.instances);
|
locals.push(...dct.instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're inside a method, don't show the modifiers
|
// if we're inside a method, don't show the modifiers
|
||||||
@@ -430,18 +436,18 @@ async function getCompletionItems(params, liveParsers, androidLibrary) {
|
|||||||
// exclude dotted (inner) types because they result in useless
|
// exclude dotted (inner) types because they result in useless
|
||||||
// matches in the intellisense filter when . is pressed
|
// matches in the intellisense filter when . is pressed
|
||||||
const types = [
|
const types = [
|
||||||
...defaultCompletionTypes.types,
|
...dct.types,
|
||||||
...sourceTypes,
|
...sourceTypes,
|
||||||
].filter(x => !x.label.includes('.'))
|
].filter(x => !x.label.includes('.'))
|
||||||
.sort(sortBy.label)
|
.sort(sortBy.label)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...locals,
|
...locals,
|
||||||
...defaultCompletionTypes.primitiveTypes,
|
...dct.primitiveTypes,
|
||||||
...defaultCompletionTypes.literals,
|
...dct.literals,
|
||||||
...modifiers,
|
...modifiers,
|
||||||
...types,
|
...types,
|
||||||
...defaultCompletionTypes.packageNames,
|
...dct.packageNames,
|
||||||
].map((x,idx) => {
|
].map((x,idx) => {
|
||||||
// to force the order above, reset sortText for each item based upon a fixed-length number
|
// to force the order above, reset sortText for each item based upon a fixed-length number
|
||||||
x.sortText = `${1000+idx}`;
|
x.sortText = `${1000+idx}`;
|
||||||
@@ -489,3 +495,4 @@ function resolveCompletionItem(item) {
|
|||||||
|
|
||||||
exports.getCompletionItems = getCompletionItems;
|
exports.getCompletionItems = getCompletionItems;
|
||||||
exports.resolveCompletionItem = resolveCompletionItem;
|
exports.resolveCompletionItem = resolveCompletionItem;
|
||||||
|
exports.clearDefaultCompletionEntries = clearDefaultCompletionEntries;
|
||||||
|
|||||||
@@ -1,22 +1,30 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { CEIType, loadAndroidLibrary } = require('java-mti');
|
const { CEIType, loadJavaLibraryCacheFile } = require('java-mti');
|
||||||
|
const { trace, time, timeEnd } = require('../logging');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} extensionPath install path of extension
|
* @param {string} extensionPath install path of extension
|
||||||
|
* @param {string[]} additional_libs set of androidx library names to include eg: ["androidx.activity:activity"]
|
||||||
* @returns {Promise<Map<string,CEIType>>}
|
* @returns {Promise<Map<string,CEIType>>}
|
||||||
*/
|
*/
|
||||||
async function loadAndroidSystemLibrary(extensionPath) {
|
async function loadAndroidSystemLibrary(extensionPath, additional_libs) {
|
||||||
console.time('android-library-load');
|
time('android-library-load');
|
||||||
let library;
|
let library;
|
||||||
try {
|
try {
|
||||||
if (!extensionPath) {
|
if (!extensionPath) {
|
||||||
throw new Error('Missing extension path')
|
throw new Error('Missing extension path')
|
||||||
}
|
}
|
||||||
const cache_folder = path.join(extensionPath, 'langserver', '.library-cache');
|
const cache_folder = path.join(extensionPath, 'langserver', '.library-cache');
|
||||||
library = await loadHighestAPIPlatform(cache_folder);
|
trace(`loading android library from ${cache_folder} with androidx libs: ${JSON.stringify(additional_libs)}`)
|
||||||
|
const typemap = await loadJavaLibraryCacheFile(path.join(cache_folder, 'android-29.zip'));
|
||||||
|
if (Array.isArray(additional_libs) && additional_libs.length) {
|
||||||
|
await loadJavaLibraryCacheFile(path.join(cache_folder, 'androidx-20200701.zip'), additional_libs, typemap);
|
||||||
|
}
|
||||||
|
trace(`loaded ${typemap.size} types into android library`);
|
||||||
|
library = typemap;
|
||||||
} finally {
|
} finally {
|
||||||
console.timeEnd('android-library-load');
|
timeEnd('android-library-load');
|
||||||
}
|
}
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
@@ -53,7 +61,7 @@ async function loadHighestAPIPlatform(cache_folder) {
|
|||||||
console.log(`loading android platform cache: ${best_match.file.name}`);
|
console.log(`loading android platform cache: ${best_match.file.name}`);
|
||||||
|
|
||||||
const cache_file = path.join(cache_folder, best_match.file.name);
|
const cache_file = path.join(cache_folder, best_match.file.name);
|
||||||
const typemap = loadAndroidLibrary(cache_file);
|
const typemap = loadJavaLibraryCacheFile(cache_file);
|
||||||
|
|
||||||
return typemap;
|
return typemap;
|
||||||
}
|
}
|
||||||
|
|||||||
5
langserver/package-lock.json
generated
5
langserver/package-lock.json
generated
@@ -282,6 +282,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||||
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||||
},
|
},
|
||||||
|
"vscode-uri": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A=="
|
||||||
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const { CEIType } = require('java-mti');
|
|||||||
|
|
||||||
const { Settings } = require('./settings');
|
const { Settings } = require('./settings');
|
||||||
const { trace } = require('./logging');
|
const { trace } = require('./logging');
|
||||||
const { getCompletionItems, resolveCompletionItem } = require('./completions');
|
const { clearDefaultCompletionEntries, getCompletionItems, resolveCompletionItem } = require('./completions');
|
||||||
const { getSignatureHelp } = require('./method-signatures');
|
const { getSignatureHelp } = require('./method-signatures');
|
||||||
const { FileURIMap, JavaDocInfo, indexAt, reparse } = require('./document');
|
const { FileURIMap, JavaDocInfo, indexAt, reparse } = require('./document');
|
||||||
|
|
||||||
@@ -32,9 +32,27 @@ let androidLibrary = null;
|
|||||||
*/
|
*/
|
||||||
const liveParsers = new FileURIMap();
|
const liveParsers = new FileURIMap();
|
||||||
|
|
||||||
|
let startupOpts = null;
|
||||||
let hasConfigurationCapability = false;
|
let hasConfigurationCapability = false;
|
||||||
let hasWorkspaceFolderCapability = false;
|
let hasWorkspaceFolderCapability = false;
|
||||||
|
|
||||||
|
function loadCodeCompletionLibrary(extensionPath, codeCompletionLibraries) {
|
||||||
|
// the android library is loaded asynchronously, with the global `androidLibrary` variable
|
||||||
|
// set to the promise while it is loading.
|
||||||
|
androidLibrary = (androidLibrary instanceof Promise
|
||||||
|
? androidLibrary // if we're currently loading, wait for it to complete
|
||||||
|
: Promise.resolve(new Map())
|
||||||
|
)
|
||||||
|
.then(() => loadAndroidSystemLibrary(extensionPath, codeCompletionLibraries))
|
||||||
|
.then(
|
||||||
|
library => androidLibrary = library,
|
||||||
|
err => {
|
||||||
|
console.log(`Android library load failed: ${err.message}\n Code completion may not be available.`);
|
||||||
|
return new Map();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Text document manager monitoring file opens and edits
|
// Text document manager monitoring file opens and edits
|
||||||
let documents = new TextDocuments({
|
let documents = new TextDocuments({
|
||||||
/**
|
/**
|
||||||
@@ -100,16 +118,21 @@ const connection = createConnection(ProposedFeatures.all);
|
|||||||
|
|
||||||
connection.onInitialize((params) => {
|
connection.onInitialize((params) => {
|
||||||
|
|
||||||
// the android library is loaded asynchronously, with the global `androidLibrary` variable
|
startupOpts = {
|
||||||
// set to the promise while it is loading.
|
extensionPath: '',
|
||||||
androidLibrary = loadAndroidSystemLibrary((params.initializationOptions || {}).extensionPath)
|
initialSettings: {
|
||||||
.then(
|
appSourceRoot: '',
|
||||||
library => androidLibrary = library,
|
/** @type {string[]} */
|
||||||
err => {
|
codeCompletionLibraries: [],
|
||||||
console.log(`Android library load failed: ${err.message}\n Code completion may not be available.`);
|
trace: false,
|
||||||
return new Map();
|
},
|
||||||
|
sourceFiles: [],
|
||||||
|
...params.initializationOptions,
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
Settings.set(startupOpts.initialSettings);
|
||||||
|
|
||||||
|
loadCodeCompletionLibrary(startupOpts.extensionPath, Settings.codeCompletionLibraries);
|
||||||
|
|
||||||
let capabilities = params.capabilities;
|
let capabilities = params.capabilities;
|
||||||
|
|
||||||
@@ -119,9 +142,8 @@ connection.onInitialize((params) => {
|
|||||||
|
|
||||||
hasWorkspaceFolderCapability = capabilities.workspace && !!capabilities.workspace.workspaceFolders;
|
hasWorkspaceFolderCapability = capabilities.workspace && !!capabilities.workspace.workspaceFolders;
|
||||||
|
|
||||||
if (params.initializationOptions) {
|
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
const file_uris = params.initializationOptions.sourceFiles || [];
|
const file_uris = Array.isArray(startupOpts.sourceFiles) ? startupOpts.sourceFiles : [];
|
||||||
for (let file_uri of file_uris) {
|
for (let file_uri of file_uris) {
|
||||||
const file = URI.parse(file_uri, true);
|
const file = URI.parse(file_uri, true);
|
||||||
const filePath = file.fsPath;
|
const filePath = file.fsPath;
|
||||||
@@ -144,7 +166,6 @@ connection.onInitialize((params) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reparse([...liveParsers.keys()], liveParsers, androidLibrary, { includeMethods: false, first_parse: true });
|
reparse([...liveParsers.keys()], liveParsers, androidLibrary, { includeMethods: false, first_parse: true });
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
capabilities: {
|
capabilities: {
|
||||||
@@ -171,10 +192,6 @@ connection.onInitialized(async () => {
|
|||||||
DidChangeConfigurationNotification.type, {
|
DidChangeConfigurationNotification.type, {
|
||||||
section: 'android-dev-ext',
|
section: 'android-dev-ext',
|
||||||
});
|
});
|
||||||
const initialSettings = await connection.workspace.getConfiguration({
|
|
||||||
section: "android-dev-ext"
|
|
||||||
});
|
|
||||||
Settings.set(initialSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasWorkspaceFolderCapability) {
|
if (hasWorkspaceFolderCapability) {
|
||||||
@@ -189,12 +206,23 @@ connection.onInitialized(async () => {
|
|||||||
connection.onDidChangeConfiguration(async (change) => {
|
connection.onDidChangeConfiguration(async (change) => {
|
||||||
trace(`onDidChangeConfiguration: ${JSON.stringify(change)}`);
|
trace(`onDidChangeConfiguration: ${JSON.stringify(change)}`);
|
||||||
|
|
||||||
|
const prev_ccl = [...new Set(Settings.codeCompletionLibraries)].sort();
|
||||||
|
|
||||||
// fetch and update the settings
|
// fetch and update the settings
|
||||||
const newSettings = await connection.workspace.getConfiguration({
|
const newSettings = await connection.workspace.getConfiguration({
|
||||||
section: "android-dev-ext"
|
section: "android-dev-ext"
|
||||||
});
|
});
|
||||||
|
|
||||||
Settings.set(newSettings);
|
Settings.set(newSettings);
|
||||||
|
|
||||||
|
const new_ccl = [...new Set(Settings.codeCompletionLibraries)].sort();
|
||||||
|
if (new_ccl.length !== prev_ccl.length || new_ccl.find((lib,idx) => lib !== prev_ccl[idx])) {
|
||||||
|
// code-completion libraries have changed - reload the android library
|
||||||
|
trace("code completion libraries changed - reloading android library and reparsing")
|
||||||
|
loadCodeCompletionLibrary(startupOpts.extensionPath, Settings.codeCompletionLibraries);
|
||||||
|
reparse([...liveParsers.keys()], liveParsers, androidLibrary, { includeMethods: false });
|
||||||
|
clearDefaultCompletionEntries();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
documents.onDidClose((e) => {
|
documents.onDidClose((e) => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
appSourceRoot: 'app/src/main',
|
appSourceRoot: 'app/src/main',
|
||||||
|
codeCompletionLibraries: [],
|
||||||
trace: false,
|
trace: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,6 +12,11 @@ const defaultSettings = {
|
|||||||
*/
|
*/
|
||||||
appSourceRoot = defaultSettings.appSourceRoot;
|
appSourceRoot = defaultSettings.appSourceRoot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of androidx libraries to include in code completion
|
||||||
|
*/
|
||||||
|
codeCompletionLibraries = defaultSettings.codeCompletionLibraries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if we log details
|
* True if we log details
|
||||||
*/
|
*/
|
||||||
|
|||||||
158
package.json
158
package.json
@@ -2,7 +2,7 @@
|
|||||||
"name": "android-dev-ext",
|
"name": "android-dev-ext",
|
||||||
"displayName": "Android",
|
"displayName": "Android",
|
||||||
"description": "Android debugging support for VS Code",
|
"description": "Android debugging support for VS Code",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"publisher": "adelphes",
|
"publisher": "adelphes",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -43,7 +43,161 @@
|
|||||||
"scope": "resource",
|
"scope": "resource",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "app/src/main",
|
"default": "app/src/main",
|
||||||
"description": "Workspace-relative path to the app source files. The specified folder should contain AndroidManifest.xml.\r\nChanges to this field require the extension to be restarted."
|
"description": "Workspace-relative path to the app source files. The specified folder should contain AndroidManifest.xml.\r\nChanges to this field require the extension or workspace to be reloaded."
|
||||||
|
},
|
||||||
|
"android-dev-ext.codeCompletionLibraries": {
|
||||||
|
"scope": "resource",
|
||||||
|
"type": "array",
|
||||||
|
"description": "Select which Android Jetpack Libraries (androidx.*) to include in code-completion results.\nNote: Switch to the JSON Settings editor for simpler editing of this list.",
|
||||||
|
"examples": [
|
||||||
|
["androidx.activity:activity"]
|
||||||
|
],
|
||||||
|
"items" : {
|
||||||
|
"type":"string",
|
||||||
|
"enum": [
|
||||||
|
"androidx.activity:activity",
|
||||||
|
"androidx.annotation:annotation",
|
||||||
|
"androidx.annotation:annotation-experimental",
|
||||||
|
"androidx.annotation:annotation-experimental-lint",
|
||||||
|
"androidx.appcompat:appcompat",
|
||||||
|
"androidx.appcompat:appcompat-resources",
|
||||||
|
"androidx.arch.core:core-common",
|
||||||
|
"androidx.arch.core:core-runtime",
|
||||||
|
"androidx.arch.core:core-testing",
|
||||||
|
"androidx.asynclayoutinflater:asynclayoutinflater",
|
||||||
|
"androidx.autofill:autofill",
|
||||||
|
"androidx.benchmark:benchmark-common",
|
||||||
|
"androidx.benchmark:benchmark-gradle-plugin",
|
||||||
|
"androidx.benchmark:benchmark-junit4",
|
||||||
|
"androidx.biometric:biometric",
|
||||||
|
"androidx.browser:browser",
|
||||||
|
"androidx.cardview:cardview",
|
||||||
|
"androidx.collection:collection",
|
||||||
|
"androidx.concurrent:concurrent-futures",
|
||||||
|
"androidx.constraintlayout:constraintlayout",
|
||||||
|
"androidx.constraintlayout:constraintlayout-solver",
|
||||||
|
"androidx.contentpager:contentpager",
|
||||||
|
"androidx.coordinatorlayout:coordinatorlayout",
|
||||||
|
"androidx.core:core",
|
||||||
|
"androidx.cursoradapter:cursoradapter",
|
||||||
|
"androidx.customview:customview",
|
||||||
|
"androidx.databinding:databinding-adapters",
|
||||||
|
"androidx.databinding:databinding-common",
|
||||||
|
"androidx.databinding:databinding-compiler",
|
||||||
|
"androidx.databinding:databinding-compiler-common",
|
||||||
|
"androidx.databinding:databinding-runtime",
|
||||||
|
"androidx.databinding:viewbinding",
|
||||||
|
"androidx.documentfile:documentfile",
|
||||||
|
"androidx.drawerlayout:drawerlayout",
|
||||||
|
"androidx.dynamicanimation:dynamicanimation",
|
||||||
|
"androidx.emoji:emoji",
|
||||||
|
"androidx.emoji:emoji-appcompat",
|
||||||
|
"androidx.emoji:emoji-bundled",
|
||||||
|
"androidx.enterprise:enterprise-feedback",
|
||||||
|
"androidx.enterprise:enterprise-feedback-testing",
|
||||||
|
"androidx.exifinterface:exifinterface",
|
||||||
|
"androidx.fragment:fragment",
|
||||||
|
"androidx.fragment:fragment-testing",
|
||||||
|
"androidx.gridlayout:gridlayout",
|
||||||
|
"androidx.heifwriter:heifwriter",
|
||||||
|
"androidx.interpolator:interpolator",
|
||||||
|
"androidx.leanback:leanback",
|
||||||
|
"androidx.leanback:leanback-preference",
|
||||||
|
"androidx.legacy:legacy-preference-v14",
|
||||||
|
"androidx.legacy:legacy-support-core-ui",
|
||||||
|
"androidx.legacy:legacy-support-core-utils",
|
||||||
|
"androidx.legacy:legacy-support-v13",
|
||||||
|
"androidx.legacy:legacy-support-v4",
|
||||||
|
"androidx.lifecycle:lifecycle-common",
|
||||||
|
"androidx.lifecycle:lifecycle-common-java8",
|
||||||
|
"androidx.lifecycle:lifecycle-compiler",
|
||||||
|
"androidx.lifecycle:lifecycle-extensions",
|
||||||
|
"androidx.lifecycle:lifecycle-livedata",
|
||||||
|
"androidx.lifecycle:lifecycle-livedata-core",
|
||||||
|
"androidx.lifecycle:lifecycle-process",
|
||||||
|
"androidx.lifecycle:lifecycle-reactivestreams",
|
||||||
|
"androidx.lifecycle:lifecycle-runtime",
|
||||||
|
"androidx.lifecycle:lifecycle-service",
|
||||||
|
"androidx.lifecycle:lifecycle-viewmodel",
|
||||||
|
"androidx.lifecycle:lifecycle-viewmodel-savedstate",
|
||||||
|
"androidx.loader:loader",
|
||||||
|
"androidx.localbroadcastmanager:localbroadcastmanager",
|
||||||
|
"androidx.media2:media2-common",
|
||||||
|
"androidx.media2:media2-exoplayer",
|
||||||
|
"androidx.media2:media2-player",
|
||||||
|
"androidx.media2:media2-session",
|
||||||
|
"androidx.media2:media2-widget",
|
||||||
|
"androidx.media:media",
|
||||||
|
"androidx.mediarouter:mediarouter",
|
||||||
|
"androidx.multidex:multidex",
|
||||||
|
"androidx.multidex:multidex-instrumentation",
|
||||||
|
"androidx.navigation:navigation-common",
|
||||||
|
"androidx.navigation:navigation-dynamic-features-fragment",
|
||||||
|
"androidx.navigation:navigation-dynamic-features-runtime",
|
||||||
|
"androidx.navigation:navigation-fragment",
|
||||||
|
"androidx.navigation:navigation-runtime",
|
||||||
|
"androidx.navigation:navigation-safe-args-generator",
|
||||||
|
"androidx.navigation:navigation-safe-args-gradle-plugin",
|
||||||
|
"androidx.navigation:navigation-testing",
|
||||||
|
"androidx.navigation:navigation-ui",
|
||||||
|
"androidx.paging:paging-common",
|
||||||
|
"androidx.paging:paging-runtime",
|
||||||
|
"androidx.paging:paging-rxjava2",
|
||||||
|
"androidx.palette:palette",
|
||||||
|
"androidx.percentlayout:percentlayout",
|
||||||
|
"androidx.preference:preference",
|
||||||
|
"androidx.print:print",
|
||||||
|
"androidx.recommendation:recommendation",
|
||||||
|
"androidx.recyclerview:recyclerview",
|
||||||
|
"androidx.recyclerview:recyclerview-selection",
|
||||||
|
"androidx.room:room-common",
|
||||||
|
"androidx.room:room-compiler",
|
||||||
|
"androidx.room:room-guava",
|
||||||
|
"androidx.room:room-migration",
|
||||||
|
"androidx.room:room-runtime",
|
||||||
|
"androidx.room:room-rxjava2",
|
||||||
|
"androidx.room:room-testing",
|
||||||
|
"androidx.savedstate:savedstate",
|
||||||
|
"androidx.sharetarget:sharetarget",
|
||||||
|
"androidx.slice:slice-builders",
|
||||||
|
"androidx.slice:slice-core",
|
||||||
|
"androidx.slice:slice-view",
|
||||||
|
"androidx.slidingpanelayout:slidingpanelayout",
|
||||||
|
"androidx.sqlite:sqlite",
|
||||||
|
"androidx.sqlite:sqlite-framework",
|
||||||
|
"androidx.swiperefreshlayout:swiperefreshlayout",
|
||||||
|
"androidx.test:core",
|
||||||
|
"androidx.test.espresso:espresso-accessibility",
|
||||||
|
"androidx.test.espresso:espresso-contrib",
|
||||||
|
"androidx.test.espresso:espresso-core",
|
||||||
|
"androidx.test.espresso:espresso-idling-resource",
|
||||||
|
"androidx.test.espresso:espresso-intents",
|
||||||
|
"androidx.test.espresso:espresso-remote",
|
||||||
|
"androidx.test.espresso:espresso-web",
|
||||||
|
"androidx.test.espresso.idling:idling-concurrent",
|
||||||
|
"androidx.test.espresso.idling:idling-net",
|
||||||
|
"androidx.test.ext:junit",
|
||||||
|
"androidx.test.ext:truth",
|
||||||
|
"androidx.test.janktesthelper:janktesthelper",
|
||||||
|
"androidx.test:monitor",
|
||||||
|
"androidx.test:rules",
|
||||||
|
"androidx.test:runner",
|
||||||
|
"androidx.test.uiautomator:uiautomator",
|
||||||
|
"androidx.transition:transition",
|
||||||
|
"androidx.tvprovider:tvprovider",
|
||||||
|
"androidx.vectordrawable:vectordrawable",
|
||||||
|
"androidx.vectordrawable:vectordrawable-animated",
|
||||||
|
"androidx.versionedparcelable:versionedparcelable",
|
||||||
|
"androidx.viewpager2:viewpager2",
|
||||||
|
"androidx.viewpager:viewpager",
|
||||||
|
"androidx.wear:wear",
|
||||||
|
"androidx.webkit:webkit",
|
||||||
|
"androidx.work:work-gcm",
|
||||||
|
"androidx.work:work-runtime",
|
||||||
|
"androidx.work:work-rxjava2",
|
||||||
|
"androidx.work:work-testing"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"android-dev-ext.subscriptionKey": {
|
"android-dev-ext.subscriptionKey": {
|
||||||
"scope": "application",
|
"scope": "application",
|
||||||
|
|||||||
Reference in New Issue
Block a user