我的Android库中更好的包结构

时间:2015-02-17 15:00:13

标签: java android package packages android-library

我正在编写(第一次)一个Android库(有自己的活动),将使用Android aar包在其他Android项目中导入。

我的目标是只发布一个类(让我们称之为MyPlugin)来完成所有提供公共方法的东西(调用活动等);但对我来说,似乎所有活动必须是public;所以我想将用户想要使用的类与我不想使用的类分开。类似的东西:

com.mycompany.myplugin.api
 |--> MyPlugin (public class with public methods)
com.mycompany.myplugin.activities
 |--> Acitivty1
 |--> ....
 |--> ActivityN (public? activities)
com.mycompany.myplugin.mystuff
 |--> Services (protected? class with protected? methods)

通过这种设计,我可以对用户说“你应该只使用api包”。

问题是Serivice类:它由Activities和MyPlugin使用,如果我想要它(或它的方法)protected它应该在同一个包中(所以最终用户看不到它)。

我知道,通过反思,最终用户可以做任何事情,但我希望尽可能简洁明了。

我找到的唯一解决方案是只有一个包含所有类的包,但正如我所说,我想将MyPlugin与活动分开。

2 个答案:

答案 0 :(得分:2)

您无法创建非公开的Android组件(Activity,Service,BroadcastReceiver)。他们的建设者也不能非公开。

通过功能而不是按组件填充您的包装通常是个好主意:例如。

|-awesomefeatureone
|----Activity1
|----Fragment1
|----AsyncTask1
|----Service1
|-awesomefeaturetwo
|----BroadcastReceiver2
|----Service2

在这种情况下,您可以使用封装(package-local可见性,protected内容来玩一些有用的技巧。

我猜你无法从最终用户隐藏你的组件类。但是你可能会禁止直接从客户端代码中运行你的一个组件:使用注释中建议的@billmuell方法,或者只使用package-local extras来启动Activity,package-local参数extras来创建Fragment ......你明白了。

public class SomeFragment extends Fragment{
    static final String ARG = "package_local_arg";
    protected void onCreate(Bundle state){
        super.onCreate(state);
        Bundle args = getArguments();
        if(args == null || !args.contains(ARG)){       
            throw new IllegalStateException();
        }
    }
}


public class SamePackageActivity extends Activity {

   public void doSometh(){
        Fragment f = new SomeFragment();
        Bundle args = new Bundle();
        args.putInt(SomeFragment.ARG, 1);
        f.setArguments();
        ...
   }
}

答案 1 :(得分:2)

一个常见的约定是将名为internal的包用于私有实现/内部类。

com.mycompany.myplugin // all public stuff here and in its subpackages
com.mycompany.myplugin.internal // all non public stuff

另外,请遵循@Drew's answer建议:

  

通过功能而不是按组件填充您的包通常是个好主意

参考文献: