nudroid-providers:Nudroid Providers - 为 Android 生成的内容提供程序

  • Z7_306628
  • 211.3KB
  • zip
  • 0
  • VIP专享
  • 0
  • 2022-06-13 20:18
#Nudroid 供应商 Nudroid 提供程序库是一组 Java 注释和随附的注释处理器,旨在减少配置和管理 Android 内容提供程序所需的工作量。 使用 Maven 和 Gradle 构建将自动调用注释处理器。 如果使用 IDE,启用注解处理并将 nudroid-annotations-processor-all.jar 注册为要执行的处理器。 有关如何使用提供的注释的更多信息,请参阅库 javadocs。 #License Nudroid Providers 根据 MIT 许可条款获得许可 版权所有 (c) 2014 Nurun Inc. 特此授予任何人免费获得本软件和相关文档文件(“软件”)副本的许可,不受限制地处理本软件,包括但不限于使用、复制、修改、合并的权利、发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的人员这样做,但须符合以下条件: 上述版
#Nudroid Providers The Nudroid providers library is a set of Java annotations and accompanying annotation processor which aims to reduce the amount of work required to configure and manage Android Content Providers. Building with Maven and Gradle will automatically invoke the annotation processor. If using an IDE, enable annotation processing and register nudroid-annotations-processor-all.jar as a processor to be executed. See the library javadocs for more information about how to use the provided annotations. #License Nudroid Providers is licensed under the terms of the MIT License Copyright (c) 2014 Nurun Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #TODO Upload demo app and link it here. #How it works. Here's how a Content Provider looks like according to Android's documentation. public class ExampleProvider extends ContentProvider { ... // Creates a UriMatcher object. private static final UriMatcher sUriMatcher; ... ... sUriMatcher.addURI("", "table3", 1); sUriMatcher.addURI("", "table3/#", 2); sUriMatcher.addURI("", "data", 3); ... // Keep adding urls and url ids. So far not that bad. public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { ... // UGH!. First WTF: a switch case. switch (sUriMatcher.match(uri)) { case 1: if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC"; break; case 2: // Second WTF: so I have to map magic positions to whatever URLs I defined above. // Guess what happens if you have dozens of URI ids. selection = selection + "_ID = " uri.getLastPathSegment(); break; case 3: // Third WTF: If you need to customize behavior using query strings, you can't define a specific URI id. // You have to do ifs inside the switch if (uri.getQueryParameter("X") != null) { // Do something with X. } else if (uri.getQueryParameter("Y") != null) { // Do something with Y. } break; default: ... // If the URI is not recognized, you should do some error handling here. } // call the code to actually do the query } The code is brittle, error prone, complex, hard to maintain and stupidly boring to write. What if instead you could do this: @ContentProvider(authority = "") // Anotate the authority once. public class ExampleProviderDelegate implements ContentProviderDelegate { // Yes. POJO class (it is not required to implement ContentProviderDelegate // if you do not need to hook up with the content provider lifecycle methods). @Query("table3") // Add the path specific URI. No more URI ids \o/. public Cursor listTable3(final @SortOrder String sortOrder) { // Method names are meaningful. No need to look at the code to know what it should do. // Only parameters we are interested in are exposed. String order = sortOrder; if (TextUtils.isEmpty(order)) order = "_ID ASC"; // Do the query with the sort order. } @Query("table3/{rowId}") public Cursor getTable3Record(final @UriPlaceholder("rowId") String rowId) { // Required data is passed in as arguments. No need to know their position in the URL. // Don't worry. The compiler will flag invalid mappings for you and your IDE will highlight the errors. String selection = "_ID = ?"; String[] selectionArgs = new String[] { rowId }; // Do the query } // URIs can be easily distinguished by query string parameters if the need arises. @Query("data?rows={rows}") public Cursor getRowsOfData(final @UriPlaceholder("rows") String rowList) { // Type conversion is in the works. // Do the query } @Query("data?cols={cols}") public Cursor getColsOfData(final @UriPlaceholder("cols") String colList) { // Type conversion is in the works. // Do the query } ... } The code is easier to understand and maintain. The compiler will do a great deal of job to validate the input parameters and the mappings. The magic is possible due to Java annotation processor which will create all the necessary boiler plate code for you every time you save a file. In fact, here's the code that the annotation processor creates for you: A content provider (with the XML snippet to register it in your manifest file): /* * This is the basic XML you can use to configure this content provider in AndroidManifest.xml * <provider * android:name="" * android:authorities="" * android:exported="<true|false>" * android:grantUriPermissions="<true|false>" * android:label="<label>" * android:readPermission="<read_permission>" * android:writePermission="<write_permission>" /> */ public class ExampleProviderContentProvider extends ContentProvider { private ExampleProviderDelegateRouter mContentProviderRouter; ... public Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return mContentProviderRouter.query(getContext(), contentUri, projection, selection, selectionArgs, sortOrder); } ... } And a Router class public class ExampleProviderDelegateRouter { static final UriMatcher URI_MATCHER; static { URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); URI_MATCHER.addURI("", "/table3/*", 1); URI_MATCHER.addURI("", "/data", 2); URI_MATCHER.addURI("", "/table3", 3); } private mDelegate; ... public Cursor query(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { ContentProviderContext contentProviderContext = null; Cursor result = null; switch (URI_MATCHER.match(uri)) { case 1: