[英]Access main project from module in Android Studio?
I am using this library which I have installed locally as a module.我正在使用我作为模块在本地安装的这个库。 I'm able to access it via my main project, but I'm not able to do the opposite.我可以通过我的主项目访问它,但我不能做相反的事情。 For example, access a variable in my main project from this library...例如,从这个库访问我的主项目中的一个变量......
I tried adding this line in the library's build.gradle
:我尝试在图书馆的build.gradle
中添加这一行:
implementation project(':app')
But I get this weird error:但我得到了这个奇怪的错误:
Circular dependency between the following tasks:
:placepicker:generateDebugRFile
\--- :placepicker:generateDebugRFile (*)
(*) - details omitted (listed previously)
How can I fix this?我怎样才能解决这个问题? My project is in Java and my library is in Kotlin我的项目在 Java 中,我的图书馆在 Kotlin
"Circular dependency" can be fixed only by removing dependency that causes this issue on one of two sides. “循环依赖”只能通过删除在两侧之一上导致此问题的依赖性来修复。
If you need to access some data from the library code you can implement an interface in a library that will be extended by some class in your project.如果您需要从库代码中访问一些数据,您可以在库中实现一个接口,该接口将由项目中的某些 class 扩展。 Then you will be able to use extended class in your library and access methods defined in the interface .然后,您将能够在您的库中使用扩展的 class 并访问接口中定义的方法。
Let's imagine you need to get a reference to the application context within your library.假设您需要在库中获取对应用程序上下文的引用。 You should create an interface:您应该创建一个接口:
interface ContextAccessor {
// Marking it as optional just in case
// you will not be able to get a context
// from an object that implemented ContextAccessor
fun getApplicationContext(): Application?
}
Because you added the library as a dependency in your project you have access to ContextAccessor
.因为您将库添加为项目中的依赖项,所以您可以访问ContextAccessor
。 Extend some class with this interface and implement the getApplicationContext
method.用这个接口扩展一些 class 并实现getApplicationContext
方法。 Let's say you want to extend some Activity
.假设您想扩展一些Activity
。
class MyActivity: Activity, ContextAccessor {
... other code here
override fun getApplicationContext(): Application? = application
}
Now from within your MyActivity
class, you can set ContextAccessor
into your library as if it was dependency injection .现在从您的MyActivity
class 中,您可以将ContextAccessor
设置到您的库中,就好像它是依赖注入一样。
class MyActivity: Activity, ContextAccessor {
... other code here
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val someLibraryClassInstance = SomeLibraryClass()
someLibraryClassInstance.setContextAccessor(this)
// OR -> `someLibraryClassInstance.contextAccessor = this`
}
}
WARNING : when you save a reference to any Android component, especially Activity, Fragment, Dialog etc., make sure you later remove this reference when the object is going to be destroyed to avoid memory leaks.警告:当您保存对任何 Android 组件的引用时,尤其是 Activity、Fragment、Dialog 等,请确保稍后在 object 将被销毁时删除此引用,以避免 ZCD69B4957F06CD818D7ZBF3D61 泄漏。
An example of how to remove a reference on a little bit modified code from the previous code snippet:如何从前面的代码片段中删除对一些修改过的代码的引用的示例:
class MyActivity: Activity, ContextAccessor {
... other code here
private val someLibraryClassInstance = SomeLibraryClass()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ContextAccessor reference is set to some library class
someLibraryClassInstance.setContextAccessor(this)
}
override fun onDestroy() {
super.onDestroy()
// Super important!
someLibraryClassInstance.setContextAccessor(null)
// OR create some method like `someLibraryClassInstance.removeContextAccessor(this)`
}
}
interface ContextAccessor {
// Marking it as optional just in case
// you will not be able to get a context
// from an object that implemented ContextAccessor
Application getApplicationContext();
}
public class MyActivity extends Activity implements MyActivity.ContextAccessor {
private SomeLibraryClass someLibraryClassInstance = SomeLibraryClass();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ContextAccessor reference is set to some library class
someLibraryClassInstance.setContextAccessor(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Super important!
someLibraryClassInstance.setContextAccessor(null);
// OR create some method like `someLibraryClassInstance.removeContextAccessor(this)`
}
@Override
public Application getApplicationContext() {
return super.getApplication();
}
}
Here is how you can use ContextAccessor
in your library:以下是在库中使用ContextAccessor
的方法:
class SomeLibraryClass {
private var mContextAccessor: ContextAccessor?
fun setContextAccessor(contextAccessor: ContextAccessor?) {
mContextAccessor = contextAccessor
}
fun someOtherMethod() {
mContextAccessor?.getAppContext()?.let { nonNullContext ->
// use nonNullContext here
}
}
}
You can move your classes that used in both modules to another (third module) and use it in your app module and another module you want.您可以将在两个模块中使用的类移动到另一个(第三个模块)并在您的应用程序模块和您想要的另一个模块中使用它。
in app module: implementation project(":third")在应用程序模块中:实施项目(“:第三”)
in second module: implementation project(":third")在第二个模块中:实施项目(“:第三”)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.