从Android Studio中的模块访问主项目? [英] Access main project from module in Android Studio?

查看:383
本文介绍了从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...

我尝试将这一行添加到库的build.gradle中:

I tried adding this line in the library's 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)

我该如何解决?我的项目是用Java编写的,而我的库是在Kotlin编写的

How can I fix this? My project is in Java and my library is in 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. Then you will be able to use extended class in your library and access methods defined in the interface.

让我们想象一下,您需要在库中获取对应用程序上下文的引用.您应该创建一个界面:

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?
}

因为您已将库作为依赖项添加到项目中,所以可以访问ContextAccessor.使用此接口扩展某些类并实现getApplicationContext方法.假设您要扩展一些Activity.

Because you added the library as a dependency in your project you have access to ContextAccessor. Extend some class with this interface and implement the getApplicationContext method. Let's say you want to extend some Activity.

class MyActivity: Activity, ContextAccessor {
    ... other code here

    override fun getApplicationContext(): Application? = application
}

现在从MyActivity类中,您可以将ContextAccessor设置为库,就好像它是依赖注入.

Now from within your MyActivity class, you can set ContextAccessor into your library as if it was dependency injection.

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`
    }
}

警告:当您保存对任何Android组件的引用,尤其是Activity,Fragment,Dialog等时,请确保以后将对象销毁时删除此引用.避免内存泄漏.

一个示例,该示例如何从先前的代码片段中删除对经过一点修改的代码的引用:

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)`
    }
}

Java中的相同类

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();
    }
}

更新(2020年8月10日):如何使用ContextAccessor?

以下是在库中使用ContextAccessor的方法:

class SomeLibraryClass {
    private var mContextAccessor: ContextAccessor?

    fun setContextAccessor(contextAccessor: ContextAccessor?) {
        mContextAccessor = contextAccessor
    }
    
    fun someOtherMethod() {
        mContextAccessor?.getAppContext()?.let { nonNullContext ->
            // use nonNullContext here
        }
    }
}

这篇关于从Android Studio中的模块访问主项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆