├── .gitignore ├── .idea ├── dictionaries │ └── asus.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── AppImage ├── 1.png ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg └── 6.jpg ├── README.md ├── app ├── .gitignore ├── .idea │ ├── libraries │ │ ├── android_android_27.xml │ │ ├── android_arch_core_common_1_1_0_jar.xml │ │ ├── android_arch_core_runtime_1_1_0.xml │ │ ├── android_arch_lifecycle_common_1_1_0_jar.xml │ │ ├── android_arch_lifecycle_livedata_core_1_1_0.xml │ │ ├── android_arch_lifecycle_runtime_1_1_0.xml │ │ ├── android_arch_lifecycle_viewmodel_1_1_0.xml │ │ ├── com_android_support_animated_vector_drawable_27_1_1.xml │ │ ├── com_android_support_appcompat_v7_27_1_1.xml │ │ ├── com_android_support_constraint_constraint_layout_1_1_3.xml │ │ ├── com_android_support_constraint_constraint_layout_solver_1_1_3_jar.xml │ │ ├── com_android_support_design_27_1_1.xml │ │ ├── com_android_support_recyclerview_v7_27_1_1.xml │ │ ├── com_android_support_support_annotations_27_1_1_jar.xml │ │ ├── com_android_support_support_compat_27_1_1.xml │ │ ├── com_android_support_support_core_ui_27_1_1.xml │ │ ├── com_android_support_support_core_utils_27_1_1.xml │ │ ├── com_android_support_support_fragment_27_1_1.xml │ │ ├── com_android_support_support_media_compat_27_1_1.xml │ │ ├── com_android_support_support_v4_27_1_1.xml │ │ ├── com_android_support_support_vector_drawable_27_1_1.xml │ │ ├── com_android_support_test_espresso_espresso_core_3_0_2.xml │ │ ├── com_android_support_test_espresso_espresso_idling_resource_3_0_2.xml │ │ ├── com_android_support_test_monitor_1_0_2.xml │ │ ├── com_android_support_test_runner_1_0_2.xml │ │ ├── com_android_support_transition_27_1_1.xml │ │ ├── com_githang_status_bar_compat_0_7.xml │ │ ├── com_github_bumptech_glide_glide_3_8_0_jar.xml │ │ ├── com_google_code_findbugs_jsr305_2_0_1_jar.xml │ │ ├── com_google_code_gson_gson_2_8_1_jar.xml │ │ ├── com_jakewharton_butterknife_8_8_1.xml │ │ ├── com_jakewharton_butterknife_annotations_8_8_1_jar.xml │ │ ├── com_jakewharton_disklrucache_2_0_2_jar.xml │ │ ├── com_shizhefei_CoolRefreshView_1_0_1.xml │ │ ├── com_shizhefei_MVCHelper_CoolRefresh_1_3_2.xml │ │ ├── com_shizhefei_MVCHelper_Library_1_3_2.xml │ │ ├── com_squareup_haha_haha_1_1_jar.xml │ │ ├── com_squareup_javawriter_2_1_1_jar.xml │ │ ├── com_squareup_leakcanary_leakcanary_analyzer_1_3_jar.xml │ │ ├── com_squareup_leakcanary_leakcanary_android_1_3.xml │ │ ├── com_squareup_leakcanary_leakcanary_watcher_1_3_jar.xml │ │ ├── com_squareup_okhttp3_okhttp_3_8_0_jar.xml │ │ ├── com_squareup_okio_okio_1_13_0_jar.xml │ │ ├── com_youth_banner_banner_1_4_10.xml │ │ ├── javax_inject_javax_inject_1_jar.xml │ │ ├── junit_junit_4_12_jar.xml │ │ ├── net_sf_kxml_kxml2_2_3_0_jar.xml │ │ ├── org_hamcrest_hamcrest_core_1_3_jar.xml │ │ ├── org_hamcrest_hamcrest_integration_1_3_jar.xml │ │ ├── org_hamcrest_hamcrest_library_1_3_jar.xml │ │ └── org_jsoup_jsoup_1_10_2_jar.xml │ ├── modules.xml │ └── vcs.xml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── piratehat │ │ └── appstore │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── android │ │ │ └── content │ │ │ └── pm │ │ │ ├── IPackageDataObserver.aidl │ │ │ ├── IPackageStatsObserver.aidl │ │ │ └── PackageStats.aidl │ ├── java │ │ └── piratehat │ │ │ ├── appstore │ │ │ ├── Bean │ │ │ │ ├── AppBean.java │ │ │ │ ├── AppDetailBean.java │ │ │ │ ├── AppDownloadInfo.java │ │ │ │ ├── BannerBean.java │ │ │ │ └── SerializableMap.java │ │ │ ├── adapter │ │ │ │ ├── ApkAdapter.java │ │ │ │ ├── CategoryAdapter.java │ │ │ │ ├── CommonAppsAdapter.java │ │ │ │ ├── DownloadAppAdapter.java │ │ │ │ ├── GameMainAdapter.java │ │ │ │ ├── ImageAdapter.java │ │ │ │ ├── MainAppsAdapter.java │ │ │ │ ├── RankAppsAdapter.java │ │ │ │ ├── SoftwareMainAdapter.java │ │ │ │ └── ViewPagerAdapter.java │ │ │ ├── app │ │ │ │ └── App.java │ │ │ ├── config │ │ │ │ ├── Constant.java │ │ │ │ ├── Download.java │ │ │ │ └── Url.java │ │ │ ├── contract │ │ │ │ ├── IAppDetailsContract.java │ │ │ │ ├── IAppsContract.java │ │ │ │ ├── IBoutiqueContract.java │ │ │ │ ├── IGameContract.java │ │ │ │ ├── IMainContract.java │ │ │ │ ├── IRankContract.java │ │ │ │ ├── ISoftwareContract.java │ │ │ │ └── ITencentContract.java │ │ │ ├── diskCache │ │ │ │ └── DiskCacheManager.java │ │ │ ├── download │ │ │ │ ├── DownloadListener.java │ │ │ │ ├── DownloadService.java │ │ │ │ ├── DownloadTask.java │ │ │ │ └── DownloadTask1.java │ │ │ ├── dto │ │ │ │ ├── AppDto.java │ │ │ │ ├── AppsDataDto.java │ │ │ │ ├── CategoryAppsDto.java │ │ │ │ └── Mapper.java │ │ │ ├── fragment │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── CategoryFragment.java │ │ │ │ ├── GameFragment.java │ │ │ │ ├── MainFragment.java │ │ │ │ ├── ManagerFragment.java │ │ │ │ ├── NormalAppsFragment.java │ │ │ │ ├── RankFragment.java │ │ │ │ ├── RefreshAppsFragment.java │ │ │ │ └── SoftwareFragment.java │ │ │ ├── module │ │ │ │ ├── AppDetailModel.java │ │ │ │ ├── BoutiqueModel.java │ │ │ │ ├── ClassifyModel.java │ │ │ │ ├── CommonAppsModel.java │ │ │ │ ├── GameModel.java │ │ │ │ ├── MainAppsModel.java │ │ │ │ ├── MainModule.java │ │ │ │ ├── OkHttpRequestHandle.java │ │ │ │ ├── RankModel.java │ │ │ │ ├── SoftwareModel.java │ │ │ │ └── TencentModel.java │ │ │ ├── presenter │ │ │ │ ├── AppDetailPresenter.java │ │ │ │ ├── AppPresenter.java │ │ │ │ ├── BoutiquePresenter.java │ │ │ │ ├── GamePresenter.java │ │ │ │ ├── MainPresenter.java │ │ │ │ ├── RankPresenter.java │ │ │ │ ├── SoftwarePresenter.java │ │ │ │ └── TencentPresenter.java │ │ │ ├── ui │ │ │ │ ├── ApkActivity.java │ │ │ │ ├── AppDetailsActivity.java │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── BoutiqueActivity.java │ │ │ │ ├── CategoryActivity.java │ │ │ │ ├── CategoryDetailsActivity.java │ │ │ │ ├── ClassifyActivity.java │ │ │ │ ├── DownloadManagerActivity.java │ │ │ │ ├── DownloadUtil.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── RankActivity.java │ │ │ │ └── TencentActivity.java │ │ │ ├── utils │ │ │ │ ├── BottomNavigationViewHelper.java │ │ │ │ ├── CacheUtil.java │ │ │ │ ├── CloseQuicklyUtil.java │ │ │ │ ├── GlideImageLoader.java │ │ │ │ ├── GsonUtil.java │ │ │ │ ├── JsoupUtil.java │ │ │ │ ├── OkHttpCookieJar.java │ │ │ │ ├── OkHttpResultCallback.java │ │ │ │ ├── OkHttpUtil.java │ │ │ │ ├── SecretUtil.java │ │ │ │ └── UnitUtil.java │ │ │ └── widget │ │ │ │ └── NoScrollViewPager.java │ │ │ ├── httpClient │ │ │ ├── BridgesInterceptor.java │ │ │ ├── Call.java │ │ │ ├── Callback.java │ │ │ ├── ConnectInterceptor.java │ │ │ ├── Dispatcher.java │ │ │ ├── HttpClient.java │ │ │ ├── Interceptor.java │ │ │ ├── NameRunnable.java │ │ │ ├── Protocol.java │ │ │ ├── RealCall.java │ │ │ ├── RealConnection.java │ │ │ ├── RealInterceptorChain.java │ │ │ ├── Request.java │ │ │ ├── Response.java │ │ │ ├── RetryInterceptor.java │ │ │ ├── SegmentInputStream.java │ │ │ └── Util.java │ │ │ └── picture │ │ │ ├── BitmapDecoder.java │ │ │ ├── BitmapRequest.java │ │ │ ├── ImageViewHelper.java │ │ │ ├── MD5Utils.java │ │ │ ├── Picture.java │ │ │ ├── RequestDispatcher.java │ │ │ ├── RequestRunnable.java │ │ │ ├── Util.java │ │ │ ├── cache │ │ │ ├── DiskCache.java │ │ │ ├── DiskLruCache │ │ │ │ └── DiskLruCache │ │ │ │ │ ├── DiskLruCache.java │ │ │ │ │ ├── DiskLruCacheManager.java │ │ │ │ │ ├── StrictLineReader.java │ │ │ │ │ ├── Util.java │ │ │ │ │ └── Utils.java │ │ │ ├── DoubleCache.java │ │ │ ├── IBitmapCache.java │ │ │ └── MemoryCache.java │ │ │ ├── config │ │ │ ├── DisplayConfig.java │ │ │ └── PictureConfig.java │ │ │ └── loader │ │ │ ├── BaseLoader.java │ │ │ ├── DiskImageLoader.java │ │ │ ├── ILoader.java │ │ │ ├── LoaderManager.java │ │ │ ├── NetImageLoader.java │ │ │ └── policy │ │ │ ├── ILoadPolicy.java │ │ │ ├── ReverseLoaderPolicy.java │ │ │ └── SerialLoadPolicy.java │ └── res │ │ ├── drawable-hdpi │ │ ├── btn_arrow_right.png │ │ ├── et_search.png │ │ ├── ibn_setting.png │ │ ├── ibn_user.png │ │ ├── imb_download.png │ │ ├── iv_game_1.png │ │ ├── iv_game_10.png │ │ ├── iv_game_2.png │ │ ├── iv_game_3.png │ │ ├── iv_game_4.png │ │ ├── iv_game_5.png │ │ ├── iv_game_6.png │ │ ├── iv_game_7.png │ │ ├── iv_game_8.png │ │ ├── iv_game_9.png │ │ ├── iv_software_1.png │ │ ├── iv_software_10.png │ │ ├── iv_software_11.png │ │ ├── iv_software_12.png │ │ ├── iv_software_13.png │ │ ├── iv_software_14.png │ │ ├── iv_software_15.png │ │ ├── iv_software_2.png │ │ ├── iv_software_3.png │ │ ├── iv_software_4.png │ │ ├── iv_software_5.png │ │ ├── iv_software_6.png │ │ ├── iv_software_7.png │ │ ├── iv_software_8.png │ │ ├── iv_software_9.png │ │ ├── tab_boutique.png │ │ ├── tab_category.png │ │ ├── tab_collection.png │ │ ├── tab_rank.png │ │ └── tab_tencent.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── download_shape.xml │ │ ├── et_shape.xml │ │ ├── ic_launcher_background.xml │ │ ├── navigation_selector.xml │ │ ├── progress_bg.xml │ │ ├── tab_selector.xml │ │ ├── tv_green_shape.xml │ │ ├── tv_orange_shape.xml │ │ └── tv_red_shape.xml │ │ ├── layout │ │ ├── activity_apk.xml │ │ ├── activity_app_details.xml │ │ ├── activity_boutique.xml │ │ ├── activity_category.xml │ │ ├── activity_category_details.xml │ │ ├── activity_classify.xml │ │ ├── activity_collection.xml │ │ ├── activity_download_manager.xml │ │ ├── activity_main.xml │ │ ├── activity_rank.xml │ │ ├── activity_tencent.xml │ │ ├── fragment_apps.xml │ │ ├── fragment_category.xml │ │ ├── fragment_game.xml │ │ ├── fragment_image.xml │ │ ├── fragment_main.xml │ │ ├── fragment_manager.xml │ │ ├── fragment_normal.xml │ │ ├── fragment_rank.xml │ │ ├── fragment_software.xml │ │ ├── include_collections.xml │ │ ├── include_edit_input.xml │ │ ├── include_tab.xml │ │ ├── item.xml │ │ ├── item_apk.xml │ │ ├── item_app.xml │ │ ├── item_banner.xml │ │ ├── item_category.xml │ │ ├── item_download.xml │ │ ├── item_gridview.xml │ │ ├── item_main_navigation.xml │ │ └── item_two_navigation.xml │ │ ├── menu │ │ ├── menu_navigation.xml │ │ └── menu_tools.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── game.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── main.png │ │ ├── manager.png │ │ └── software.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── piratehat │ └── appstore │ └── ExampleUnitTest.java ├── build.gradle ├── build.prop ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/dictionaries/asus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jsoup 5 | tencent 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppImage/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/1.png -------------------------------------------------------------------------------- /AppImage/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/2.jpg -------------------------------------------------------------------------------- /AppImage/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/3.jpg -------------------------------------------------------------------------------- /AppImage/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/4.jpg -------------------------------------------------------------------------------- /AppImage/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/5.jpg -------------------------------------------------------------------------------- /AppImage/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/AppImage/6.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### AppStore 2 | 个人学习小项目,简单实现应用宝功能,数据来源与网站,侵权删。 3 | #### 实现的功能 4 | - MVP 模式 5 | - ~~封装 OkHttp 后台服务断点续传下载~~ 6 | - 封装 Socket 进行 HTTP GET 请求 7 | - 封装 LruCache 和 DiskLruCache 缓存 8 | - 采用 Jsoup 抓取网站数据 9 | - 采用反射和 AIDL 获取应用缓存 10 | - ~~Glide 加载图片~~ 11 | - 实现简易图片加载框架 12 | #### 实现情况截图 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_android_27.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_core_common_1_1_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_core_runtime_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_lifecycle_common_1_1_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_lifecycle_livedata_core_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_lifecycle_runtime_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/android_arch_lifecycle_viewmodel_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_animated_vector_drawable_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_appcompat_v7_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_constraint_constraint_layout_1_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_constraint_constraint_layout_solver_1_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_design_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_recyclerview_v7_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_annotations_27_1_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_compat_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_core_ui_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_core_utils_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_fragment_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_media_compat_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_v4_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_support_vector_drawable_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_test_espresso_espresso_core_3_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_test_espresso_espresso_idling_resource_3_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_test_monitor_1_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_test_runner_1_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_android_support_transition_27_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_githang_status_bar_compat_0_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_github_bumptech_glide_glide_3_8_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_google_code_findbugs_jsr305_2_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_google_code_gson_gson_2_8_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_jakewharton_butterknife_8_8_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_jakewharton_butterknife_annotations_8_8_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_jakewharton_disklrucache_2_0_2_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_shizhefei_CoolRefreshView_1_0_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_shizhefei_MVCHelper_CoolRefresh_1_3_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_shizhefei_MVCHelper_Library_1_3_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_haha_haha_1_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_javawriter_2_1_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_leakcanary_leakcanary_analyzer_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_leakcanary_leakcanary_android_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_leakcanary_leakcanary_watcher_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_okhttp3_okhttp_3_8_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_squareup_okio_okio_1_13_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/com_youth_banner_banner_1_4_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/.idea/libraries/javax_inject_javax_inject_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/junit_junit_4_12_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/net_sf_kxml_kxml2_2_3_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/.idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/org_hamcrest_hamcrest_integration_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/org_hamcrest_hamcrest_library_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/libraries/org_jsoup_jsoup_1_10_2_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "piratehat.appstore" 7 | minSdkVersion 22 8 | targetSdkVersion 27 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation 'com.android.support:appcompat-v7:27.1.1' 25 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 26 | testImplementation 'junit:junit:4.12' 27 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 29 | 30 | compile 'com.android.support:design:27.1.1' 31 | compile 'org.jsoup:jsoup:1.10.2' 32 | compile 'com.squareup.okhttp3:okhttp:3.8.0' 33 | compile 'com.jakewharton:butterknife:8.8.1' 34 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' 35 | compile 'com.github.bumptech.glide:glide:3.8.0' 36 | compile 'com.githang:status-bar-compat:0.7' 37 | compile 'com.youth.banner:banner:1.4.10' 38 | compile 'com.google.code.gson:gson:2.8.1' 39 | compile 'com.shizhefei:MVCHelper-Library:1.3.2' 40 | compile 'com.shizhefei:CoolRefreshView:1.0.1' 41 | compile 'com.shizhefei:MVCHelper-CoolRefresh:1.3.2' 42 | compile 'com.jakewharton:disklrucache:2.0.2' 43 | debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' 44 | releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3' 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/piratehat/appstore/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("piratehat.appstore", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/aidl/android/content/pm/IPackageDataObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | package android.content.pm; 18 | 19 | /** 20 | * API for package data change related callbacks from the Package Manager. 21 | * Some usage scenarios include deletion of cache directory, generate 22 | * statistics related to code, data, cache usage(TODO) 23 | * {@hide} 24 | */ 25 | interface IPackageDataObserver { 26 | oneway void onRemoveCompleted(in String packageName, boolean succeeded); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/aidl/android/content/pm/IPackageStatsObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | package android.content.pm; 19 | 20 | import android.content.pm.PackageStats; 21 | /** 22 | * API for package data change related callbacks from the Package Manager. 23 | * Some usage scenarios include deletion of cache directory, generate 24 | * statistics related to code, data, cache usage(TODO) 25 | * {@hide} 26 | */ 27 | interface IPackageStatsObserver { 28 | 29 | oneway void onGetStatsCompleted(in PackageStats pStats, boolean succeeded); 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/aidl/android/content/pm/PackageStats.aidl: -------------------------------------------------------------------------------- 1 | /* //device/java/android/android/view/WindowManager.aidl 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | package android.content.pm; 19 | 20 | parcelable PackageStats; 21 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/Bean/AppDownloadInfo.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.Bean; 2 | 3 | /** 4 | * Created by PirateHat on 2018/11/22. 5 | */ 6 | 7 | public class AppDownloadInfo { 8 | private String mName; 9 | private String mIcon; 10 | private int mDownloadProgress; 11 | private int mState; 12 | 13 | public String getName() { 14 | return mName == null ? "" : mName; 15 | } 16 | 17 | public void setName(String name) { 18 | mName = name; 19 | } 20 | 21 | public String getIcon() { 22 | return mIcon == null ? "" : mIcon; 23 | } 24 | 25 | public void setIcon(String icon) { 26 | mIcon = icon; 27 | } 28 | 29 | public int getDownloadProgress() { 30 | return mDownloadProgress; 31 | } 32 | 33 | public void setDownloadProgress(int downloadProgress) { 34 | mDownloadProgress = downloadProgress; 35 | } 36 | 37 | public int getState() { 38 | return mState; 39 | } 40 | 41 | public void setState(int state) { 42 | mState = state; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/Bean/BannerBean.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.Bean; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by PirateHat on 2018/10/27. 7 | */ 8 | 9 | public class BannerBean implements Serializable { 10 | 11 | private String mImageUrl; 12 | private String mDetailUrl; 13 | private String mName; 14 | 15 | public String getImageUrl() { 16 | return mImageUrl == null ? "" : mImageUrl; 17 | } 18 | 19 | public BannerBean setImageUrl(String imageUrl) { 20 | mImageUrl = imageUrl; 21 | return this; 22 | } 23 | 24 | public String getDetailUrl() { 25 | return mDetailUrl == null ? "" : mDetailUrl; 26 | } 27 | 28 | public BannerBean setDetailUrl(String detailUrl) { 29 | mDetailUrl = detailUrl; 30 | return this; 31 | } 32 | 33 | public String getName() { 34 | return mName == null ? "" : mName; 35 | } 36 | 37 | public BannerBean setName(String name) { 38 | mName = name; 39 | return this; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/Bean/SerializableMap.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.Bean; 2 | 3 | import java.io.Serializable; 4 | import java.util.Map; 5 | 6 | /** 7 | * 8 | * 9 | * Created by PirateHat on 2018/11/1. 10 | */ 11 | @Deprecated 12 | public class SerializableMap implements Serializable { 13 | private Map mMap; 14 | 15 | public SerializableMap(Map map) { 16 | mMap = map; 17 | } 18 | 19 | public Map getMap() { 20 | return mMap; 21 | } 22 | 23 | public void setMap(Map map) { 24 | mMap = map; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/adapter/ApkAdapter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import java.util.List; 12 | 13 | import butterknife.BindView; 14 | import piratehat.appstore.R; 15 | 16 | /** 17 | * 18 | * Created by PirateHat on 2018/11/23. 19 | */ 20 | 21 | public class ApkAdapter extends RecyclerView.Adapter { 22 | 23 | private Context mContext; 24 | private List mList; 25 | 26 | public ApkAdapter(Context context, List list) { 27 | mContext = context; 28 | mList = list; 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 34 | return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_apk, parent, false)); 35 | } 36 | 37 | @Override 38 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { 39 | ((ViewHolder) holder).mTvName.setText(mList.get(position)); 40 | } 41 | 42 | @Override 43 | public int getItemCount() { 44 | return 0; 45 | } 46 | 47 | class ViewHolder extends RecyclerView.ViewHolder { 48 | @BindView(R.id.tv_name) 49 | TextView mTvName; 50 | 51 | public ViewHolder(View itemView) { 52 | super(itemView); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/adapter/ImageAdapter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.adapter; 2 | 3 | import android.content.Context; 4 | 5 | import android.support.v4.view.PagerAdapter; 6 | import android.text.TextUtils; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ImageView; 11 | 12 | import com.bumptech.glide.Glide; 13 | 14 | import java.util.List; 15 | 16 | import piratehat.appstore.R; 17 | 18 | /** 19 | * 20 | * Created by PirateHat on 2018/11/21. 21 | */ 22 | 23 | public class ImageAdapter extends PagerAdapter { 24 | 25 | private List mUrl; 26 | private Context mContext; 27 | 28 | public ImageAdapter(List url, Context context) { 29 | mUrl = url; 30 | mContext = context; 31 | } 32 | 33 | @Override 34 | public int getCount() { 35 | return mUrl.size(); 36 | } 37 | 38 | /** 39 | * 该函数用来判断instantiateItem(ViewGroup, int) 40 | * 函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View) 41 | */ 42 | @Override 43 | public boolean isViewFromObject(View view, Object object) { 44 | //几乎是固定的写法, 45 | return view == object; 46 | } 47 | 48 | /** 49 | * 返回要显示的view,即要显示的视图 50 | */ 51 | @Override 52 | public Object instantiateItem(ViewGroup container, int position) { 53 | View view = LayoutInflater.from(mContext).inflate(R.layout.fragment_image, null); 54 | ImageView imageView = view.findViewById(R.id.imv_icon); 55 | String url = mUrl.get(position); 56 | if (!TextUtils.isEmpty(url)) { 57 | Glide.with(mContext).load(url).into(imageView); 58 | } 59 | 60 | container.addView(view); //这一步很重要 61 | return view; 62 | } 63 | 64 | /** 65 | * 销毁条目 66 | */ 67 | @Override 68 | public void destroyItem(ViewGroup container, int position, Object object) { 69 | container.removeView((View) object); 70 | } 71 | 72 | @Override 73 | public float getPageWidth(int position) { 74 | return (float) 0.33; 75 | } 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/adapter/RankAppsAdapter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import com.bumptech.glide.Glide; 13 | 14 | import java.util.List; 15 | 16 | import butterknife.BindView; 17 | import butterknife.ButterKnife; 18 | import piratehat.appstore.Bean.AppBean; 19 | import piratehat.appstore.R; 20 | 21 | 22 | /** 23 | * 24 | * Created by PirateHat on 2018/11/1. 25 | */ 26 | 27 | public class RankAppsAdapter extends RecyclerView.Adapter { 28 | 29 | private List mAppBeans; 30 | private Context mContext; 31 | 32 | public RankAppsAdapter(List appBeans, Context context) { 33 | 34 | mAppBeans = appBeans; 35 | mContext = context; 36 | } 37 | 38 | @NonNull 39 | @Override 40 | public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 41 | return new ItemViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_app,parent,false)); 42 | } 43 | 44 | @Override 45 | public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { 46 | AppBean appBean = mAppBeans.get(position); 47 | Glide.with(mContext).load(appBean.getIconUrl()).into(holder.mImvIcon); 48 | holder.mTvHot.setText(appBean.getHot()); 49 | holder.mTvName.setText(appBean.getName()); 50 | //holder.mBtnDownload 51 | 52 | } 53 | 54 | @Override 55 | public int getItemCount() { 56 | return mAppBeans.size(); 57 | } 58 | 59 | class ItemViewHolder extends RecyclerView.ViewHolder { 60 | @BindView(R.id.imv_icon) 61 | ImageView mImvIcon; 62 | @BindView(R.id.tv_name) 63 | TextView mTvName; 64 | @BindView(R.id.tv_info) 65 | TextView mTvInfo; 66 | @BindView(R.id.tv_hot) 67 | TextView mTvHot; 68 | @BindView(R.id.btn_download) 69 | TextView mBtnDownload; 70 | 71 | ItemViewHolder(View itemView) { 72 | super(itemView); 73 | ButterKnife.bind(this, itemView); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/adapter/ViewPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.adapter; 2 | 3 | 4 | 5 | 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentPagerAdapter; 9 | 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by PirateHat on 2018/10/27. 16 | */ 17 | 18 | public class ViewPagerAdapter extends FragmentPagerAdapter { 19 | private List mFragments; 20 | private FragmentManager mFragmentManager; 21 | 22 | public ViewPagerAdapter(FragmentManager fm) { 23 | super(fm); 24 | mFragments = new ArrayList<>(); 25 | mFragmentManager = fm; 26 | } 27 | 28 | @Override 29 | public android.support.v4.app.Fragment getItem(int position) { 30 | return mFragments.get(position); 31 | } 32 | 33 | @Override 34 | public int getCount() { 35 | return mFragments.size(); 36 | } 37 | 38 | public void addFragment(Fragment fragment) { 39 | mFragments.add(fragment); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/app/App.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.app; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.content.pm.PackageInfo; 6 | import android.content.pm.PackageManager; 7 | 8 | import com.squareup.leakcanary.LeakCanary; 9 | import com.squareup.leakcanary.RefWatcher; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.net.HttpURLConnection; 14 | import java.net.URL; 15 | 16 | /** 17 | * Created by PirateHat on 2018/10/27. 18 | */ 19 | 20 | public class App extends Application { 21 | private static File mkdirs; 22 | private static File mCache; 23 | private static Context mContext; 24 | private static RefWatcher mRerWatcher; 25 | 26 | 27 | @Override 28 | public void onCreate() { 29 | super.onCreate(); 30 | if (LeakCanary.isInAnalyzerProcess(this)) {//1 31 | // This process is dedicated to LeakCanary for heap analysis. 32 | // You should not init your app in this process. 33 | return; 34 | } 35 | mRerWatcher = LeakCanary.install(this); 36 | 37 | mCache = getExternalCacheDir(); 38 | 39 | mContext = getApplicationContext(); 40 | 41 | 42 | } 43 | 44 | public static RefWatcher getmRerWatcher() { 45 | return mRerWatcher; 46 | } 47 | 48 | public static Context getContext() { 49 | return mContext; 50 | } 51 | 52 | /** 53 | * 获取应用的版本号 54 | * 55 | * @return 应用版本号,默认返回1 56 | */ 57 | public static int getAppVersionCode() { 58 | try { 59 | PackageInfo info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0); 60 | return info.versionCode; 61 | } catch (PackageManager.NameNotFoundException e) { 62 | e.printStackTrace(); 63 | } 64 | return 1; 65 | } 66 | 67 | public static File getDir() { 68 | if (mkdirs != null && mkdirs.exists()) { 69 | return mkdirs; 70 | } 71 | 72 | mkdirs = new File(mCache, "download"); 73 | if (!mkdirs.exists()) { 74 | mkdirs.mkdirs(); 75 | } 76 | return mkdirs; 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/config/Download.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.config; 2 | 3 | /** 4 | * Created by PirateHat on 2018/11/21. 5 | */ 6 | 7 | public class Download { 8 | public static class State{ 9 | public final static int NEW = 0; 10 | public final static int DOWNLOADING = 1; 11 | public static final int FINISHED = 2; 12 | public static final int PAUSE = 3; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/config/Url.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.config; 2 | 3 | /** 4 | * 5 | * 6 | * Created by PirateHat on 2018/10/27. 7 | */ 8 | 9 | public class Url { 10 | //广场的 11 | public static final String MAIN_PAGE = "https://sj.qq.com/myapp/"; 12 | 13 | 14 | //获取所有的应用的信息 15 | public static final String LOAD_MORE = "https://sj.qq.com/myapp/cate/appList.htm?orgame=1&categoryId=0&pageSize=20&pageContext="; 16 | 17 | 18 | //分类种类 19 | public static final String CATEGORY = "https://android.myapp.com/myapp/searchAjax.htm?kw="; 20 | 21 | public static final String[] MORE_MODE = new String[]{"&pns=&sid=" 22 | , "&pns=MTA=&sid=0", 23 | "&pns=MjA=&sid=0", 24 | "&pns=MzA=&sid=0", 25 | "&pns=NDA=&sid=0", 26 | "&pns=NTA=&sid=0", 27 | "&pns=NjA=&sid=0"}; 28 | // 腾讯的种类 29 | public static final String TENCENT_PAGE = "https://sj.qq.com/myapp/cate/appList.htm?orgame=1&categoryId=-10&pageSize=20&pageContext="; 30 | 31 | 32 | public static final String SOFTWARE_ALL = "https://sj.qq.com/myapp/cate/appList.htm?orgame=1&categoryId=0&pageSize=20&pageContext="; 33 | 34 | public static final String GAME_ALL = "https://sj.qq.com/myapp/cate/appList.htm?orgame=2&categoryId=0&pageSize=20&pageContext="; 35 | public static final String CLASSIFY_ROOT = "https://sj.qq.com/myapp/cate/appList.htm?orgame=2&categoryId="; 36 | public static final String CLASSIFY_CONTEXT = "&pageSize=20&pageContext="; 37 | public static final String DETAIL_INFO = "https://sj.qq.com/myapp/detail.htm?apkName="; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IAppDetailsContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import android.content.Context; 4 | 5 | import piratehat.appstore.Bean.AppDetailBean; 6 | 7 | /** 8 | * Created by PirateHat on 2018/11/20. 9 | */ 10 | 11 | public interface IAppDetailsContract { 12 | interface IView { 13 | void setAppInfo(AppDetailBean appInfo); 14 | void showError(String msg); 15 | } 16 | 17 | 18 | interface IModel { 19 | void getAppDetailInfo(IPresenter presenter,String apkName); 20 | 21 | } 22 | 23 | interface IPresenter { 24 | void setAppInfo(AppDetailBean appInfo); 25 | void showError(String msg); 26 | void getAppDetailInfo(String apkName); 27 | void download(String name,String url); 28 | 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IAppsContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import piratehat.appstore.Bean.AppBean; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/11/3. 13 | */ 14 | 15 | public interface IAppsContract { 16 | 17 | 18 | interface IView{ 19 | void setResult(ArrayList beans); 20 | void showError(String msg); 21 | } 22 | 23 | interface IModel extends IAsyncDataSource>{ 24 | void getCategory(IPresenter presenter,String category); 25 | } 26 | 27 | interface IPresenter{ 28 | void setResult(ArrayList beans); 29 | void getCategory(String category); 30 | void showError(String msg); 31 | IAsyncDataSource getAppsData(String category); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IBoutiqueContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import android.net.IpPrefix; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by PirateHat on 2018/11/23. 9 | */ 10 | 11 | public interface IBoutiqueContract { 12 | 13 | interface IView{ 14 | void showError(String msg); 15 | void setBoutiqueMap(Map map); 16 | } 17 | 18 | interface IModel{ 19 | void getBoutiqueMap(IPresenter presenter); 20 | } 21 | 22 | interface IPresenter{ 23 | void showError(String msg); 24 | void setBoutiqueMap(Map map); 25 | void getBoutiqueMap(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IGameContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import piratehat.appstore.Bean.AppBean; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/11/13. 13 | */ 14 | 15 | public interface IGameContract { 16 | 17 | interface IView{ 18 | void setAllApps(List list); 19 | } 20 | 21 | interface IModel extends IAsyncDataSource>{ 22 | void getAllApps(IPresenter presenter); 23 | } 24 | 25 | interface IPresenter{ 26 | void setAppsList(ArrayList beans); 27 | void getAppsList(); 28 | void showError(String msg); 29 | IAsyncDataSource loadMore(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IMainContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | import com.shizhefei.mvc.IDataSource; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import piratehat.appstore.Bean.AppBean; 11 | import piratehat.appstore.Bean.BannerBean; 12 | 13 | /** 14 | * 15 | * Created by PirateHat on 2018/10/27. 16 | */ 17 | 18 | public interface IMainContract { 19 | 20 | interface IView{ 21 | void setBanner(ArrayList beans,ArrayList titles); 22 | void setRankApps(Map> beans); 23 | void setBoutiqueApps(Map> beans); 24 | void showError(String msg); 25 | } 26 | 27 | interface IModel{ 28 | void getMainPage(IPresenter presenter); 29 | 30 | 31 | } 32 | 33 | interface IPresenter{ 34 | void getMainPage(); 35 | void setBanner(ArrayList beans); 36 | void setRankApps(Map> beans); 37 | void setBoutiqueApps(Map> beans); 38 | void showError(String msg); 39 | IAsyncDataSource getRefreshData(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/IRankContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by PirateHat on 2018/11/23. 7 | */ 8 | 9 | public interface IRankContract { 10 | interface IView{ 11 | void showError(String msg); 12 | void setRankMap(Map map); 13 | } 14 | 15 | interface IModel{ 16 | void getRankMap(IPresenter presenter); 17 | } 18 | 19 | 20 | interface IPresenter{ 21 | void showError(String msg); 22 | void setRankMap(Map map); 23 | void getRankMap(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/ISoftwareContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import piratehat.appstore.Bean.AppBean; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/11/13. 13 | */ 14 | 15 | public interface ISoftwareContract { 16 | 17 | interface IView{ 18 | void setAllApps(List list); 19 | } 20 | 21 | interface IModel extends IAsyncDataSource>{ 22 | void getAllApps(IPresenter presenter); 23 | } 24 | 25 | interface IPresenter{ 26 | void setAppsList(ArrayList beans); 27 | void getAppsList(); 28 | void showError(String msg); 29 | IAsyncDataSource loadMore(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/contract/ITencentContract.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.contract; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import piratehat.appstore.Bean.AppBean; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/11/5. 13 | */ 14 | 15 | public interface ITencentContract { 16 | 17 | interface IView{ 18 | void setAppsList(ArrayList beans); 19 | 20 | void showError(String msg); 21 | 22 | } 23 | interface IModel extends IAsyncDataSource>{ 24 | 25 | void getAppsList(IPresenter presenter); 26 | } 27 | 28 | interface IPresenter { 29 | void setAppsList(ArrayList beans); 30 | void getAppsList(); 31 | void showError(String msg); 32 | IAsyncDataSource loadMore(); 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/download/DownloadListener.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.download; 2 | 3 | /** 4 | * Created by PirateHat on 2018/11/24. 5 | */ 6 | 7 | public interface DownloadListener { 8 | 9 | /** 10 | * 通知当前的下载进度 11 | * @param progress 12 | */ 13 | void onProgress(int progress); 14 | 15 | /** 16 | * 通知下载成功 17 | */ 18 | void onSuccess(); 19 | 20 | /** 21 | * 通知下载失败 22 | */ 23 | void onFailed(); 24 | 25 | /** 26 | * 通知下载暂停 27 | */ 28 | void onPaused(); 29 | 30 | /** 31 | * 通知下载取消事件 32 | */ 33 | void onCanceled(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/dto/AppsDataDto.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import piratehat.appstore.Bean.AppBean; 7 | 8 | /** 9 | * 10 | * 11 | * Created by PirateHat on 2018/10/28. 12 | */ 13 | 14 | public class AppsDataDto implements Mapper>{ 15 | private int count; 16 | private List obj; 17 | private boolean success; 18 | private String msg; 19 | 20 | 21 | @Override 22 | public List transform() { 23 | ArrayList appBeans = new ArrayList<>(); 24 | int size = obj!=null?obj.size():0; 25 | for (int i = 0; i < size; i++) { 26 | appBeans.add(obj.get(i).transform()); 27 | } 28 | return appBeans; 29 | } 30 | 31 | public int getCount() { 32 | return count; 33 | } 34 | 35 | public void setCount(int count) { 36 | this.count = count; 37 | } 38 | 39 | public List getObj() { 40 | return obj; 41 | } 42 | 43 | public void setObj(List obj) { 44 | this.obj = obj; 45 | } 46 | 47 | public boolean isSuccess() { 48 | return success; 49 | } 50 | 51 | public void setSuccess(boolean success) { 52 | this.success = success; 53 | } 54 | 55 | public String getMsg() { 56 | return msg == null ? "" : msg; 57 | } 58 | 59 | public void setMsg(String msg) { 60 | this.msg = msg; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/dto/CategoryAppsDto.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.dto; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import piratehat.appstore.Bean.AppBean; 8 | 9 | /** 10 | * 11 | * Created by PirateHat on 2018/11/3. 12 | */ 13 | 14 | public class CategoryAppsDto implements Mapper> { 15 | private int total; 16 | private int count; 17 | private boolean success; 18 | private String msg; 19 | private Obj obj; 20 | 21 | @Override 22 | public List transform() { 23 | ArrayList appBeans = new ArrayList<>(); 24 | int size = obj!=null?obj.getAppDetails().size():0; 25 | for (int i = 0; i < size; i++) { 26 | appBeans.add(obj.getAppDetails().get(i).transform()); 27 | } 28 | return appBeans; 29 | } 30 | 31 | public int getTotal() { 32 | return total; 33 | } 34 | 35 | public void setTotal(int total) { 36 | this.total = total; 37 | } 38 | 39 | public int getCount() { 40 | return count; 41 | } 42 | 43 | public void setCount(int count) { 44 | this.count = count; 45 | } 46 | 47 | public boolean isSuccess() { 48 | return success; 49 | } 50 | 51 | public void setSuccess(boolean success) { 52 | this.success = success; 53 | } 54 | 55 | public String getMsg() { 56 | return msg == null ? "" : msg; 57 | } 58 | 59 | public void setMsg(String msg) { 60 | this.msg = msg; 61 | } 62 | 63 | public Obj getObj() { 64 | return obj; 65 | } 66 | 67 | public void setObj(Obj obj) { 68 | this.obj = obj; 69 | } 70 | 71 | class Obj { 72 | private List appDetails; 73 | private int hasNext; 74 | 75 | public List getAppDetails() { 76 | return appDetails; 77 | } 78 | 79 | public void setAppDetails(List appDetails) { 80 | this.appDetails = appDetails; 81 | } 82 | 83 | public int getHasNext() { 84 | return hasNext; 85 | } 86 | 87 | public void setHasNext(int hasNext) { 88 | this.hasNext = hasNext; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/dto/Mapper.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.dto; 2 | 3 | /** 4 | * 5 | * 6 | * Created by PirateHat on 2018/10/28. 7 | */ 8 | 9 | 10 | public interface Mapper { 11 | T transform(); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/fragment/NormalAppsFragment.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import java.io.Serializable; 11 | import java.util.ArrayList; 12 | import java.util.Collection; 13 | import java.util.List; 14 | 15 | import butterknife.BindView; 16 | import butterknife.ButterKnife; 17 | import butterknife.Unbinder; 18 | import piratehat.appstore.Bean.AppBean; 19 | import piratehat.appstore.R; 20 | import piratehat.appstore.adapter.CommonAppsAdapter; 21 | import piratehat.appstore.app.App; 22 | 23 | /** 24 | * 25 | * 26 | * Created by PirateHat on 2018/11/6. 27 | */ 28 | 29 | public class NormalAppsFragment extends BaseFragment { 30 | 31 | @BindView(R.id.rv_apps) 32 | RecyclerView mRvApps; 33 | 34 | private List mAppBeans; 35 | private CommonAppsAdapter mAdapter; 36 | 37 | @Override 38 | protected void onFragmentVisibleChange(boolean isVisible) { 39 | if (isVisible){ 40 | 41 | } 42 | } 43 | 44 | @Override 45 | protected int setLayoutResId() { 46 | return R.layout.fragment_normal; 47 | } 48 | 49 | @Override 50 | protected void initData(Bundle bundle) { 51 | 52 | mAppBeans = new ArrayList<>(); 53 | ArrayList list = (ArrayList) bundle.getSerializable("apps"); 54 | if (list!=null ){ 55 | mAppBeans.addAll(list); 56 | } 57 | mAdapter = new CommonAppsAdapter(mActivity, mAppBeans); 58 | 59 | } 60 | 61 | @Override 62 | protected void initView() { 63 | mRvApps.setLayoutManager(new LinearLayoutManager(mActivity, LinearLayoutManager.VERTICAL, false)); 64 | mRvApps.setAdapter(mAdapter); 65 | } 66 | 67 | @Override 68 | protected void initListener() { 69 | 70 | } 71 | 72 | public static NormalAppsFragment newInstance(ArrayList appBeans) { 73 | NormalAppsFragment fragment = new NormalAppsFragment(); 74 | Bundle bundle = new Bundle(); 75 | bundle.putSerializable("apps", appBeans); 76 | fragment.setArguments(bundle); 77 | return fragment; 78 | } 79 | 80 | 81 | @Override 82 | public void onDestroy() { 83 | super.onDestroy(); 84 | App.getmRerWatcher().watch(this); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/fragment/RankFragment.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | 8 | 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import butterknife.BindView; 14 | 15 | 16 | import piratehat.appstore.Bean.AppBean; 17 | import piratehat.appstore.R; 18 | import piratehat.appstore.adapter.RankAppsAdapter; 19 | import piratehat.appstore.app.App; 20 | 21 | /** 22 | * 23 | * Created by PirateHat on 2018/10/31. 24 | */ 25 | 26 | public class RankFragment extends BaseFragment { 27 | 28 | 29 | @BindView(R.id.rv_apps) 30 | RecyclerView mRvApps; 31 | 32 | private List mAppBeans; 33 | private RankAppsAdapter mAppsAdapter; 34 | 35 | @Override 36 | protected void onFragmentVisibleChange(boolean isVisible) { 37 | if (isVisible){ 38 | 39 | } 40 | } 41 | @Override 42 | protected int setLayoutResId() { 43 | return R.layout.fragment_rank; 44 | } 45 | 46 | @Override 47 | protected void initData(Bundle bundle) { 48 | 49 | mAppBeans = new ArrayList<>(); 50 | ArrayList list = (ArrayList) bundle.getSerializable("apps"); 51 | if (list!=null ){ 52 | mAppBeans.addAll(list); 53 | } 54 | 55 | mAppsAdapter = new RankAppsAdapter(mAppBeans,mActivity); 56 | } 57 | 58 | @Override 59 | protected void initView() { 60 | mRvApps.setLayoutManager(new LinearLayoutManager(mActivity,LinearLayoutManager.VERTICAL,false)); 61 | mRvApps.setAdapter(mAppsAdapter); 62 | } 63 | 64 | @Override 65 | protected void initListener() { 66 | 67 | } 68 | 69 | public static RankFragment newInstance(ArrayList appBeans){ 70 | RankFragment fragment = new RankFragment(); 71 | Bundle bundle = new Bundle(); 72 | bundle.putSerializable("apps", appBeans); 73 | fragment.setArguments(bundle); 74 | return fragment; 75 | } 76 | 77 | @Override 78 | public void onDestroy() { 79 | super.onDestroy(); 80 | App.getmRerWatcher().watch(this); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/module/AppDetailModel.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.module; 2 | 3 | 4 | 5 | 6 | 7 | import java.util.HashMap; 8 | 9 | import java.util.Map; 10 | 11 | import okhttp3.Call; 12 | 13 | 14 | 15 | import piratehat.appstore.config.Constant; 16 | import piratehat.appstore.config.Url; 17 | import piratehat.appstore.contract.IAppDetailsContract; 18 | 19 | 20 | import piratehat.appstore.utils.JsoupUtil; 21 | import piratehat.appstore.utils.OkHttpResultCallback; 22 | import piratehat.appstore.utils.OkHttpUtil; 23 | 24 | /** 25 | * Created by PirateHat on 2018/11/20. 26 | */ 27 | 28 | public class AppDetailModel implements IAppDetailsContract.IModel { 29 | 30 | 31 | @Override 32 | public void getAppDetailInfo(final IAppDetailsContract.IPresenter presenter, String apkName) { 33 | 34 | 35 | 36 | Map map = new HashMap<>(); 37 | map.put(Constant.USER_AGENT, Constant.USER_AGENT_VALUE); 38 | OkHttpUtil.getInstance().getAsync(Url.DETAIL_INFO+apkName, new OkHttpResultCallback() { 39 | @Override 40 | public void onError(Call call, Exception e) { 41 | 42 | presenter.showError(e.getMessage()); 43 | } 44 | 45 | @Override 46 | public void onResponse(String msg) { 47 | presenter.setAppInfo(JsoupUtil.getInstance().getAppDetailInfo(msg)); 48 | } 49 | }, map); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/module/BoutiqueModel.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.module; 2 | 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import okhttp3.Call; 8 | 9 | import piratehat.appstore.config.Constant; 10 | import piratehat.appstore.config.Url; 11 | import piratehat.appstore.contract.IBoutiqueContract; 12 | import piratehat.appstore.utils.JsoupUtil; 13 | import piratehat.appstore.utils.OkHttpResultCallback; 14 | import piratehat.appstore.utils.OkHttpUtil; 15 | 16 | /** 17 | * Created by PirateHat on 2018/11/23. 18 | */ 19 | 20 | public class BoutiqueModel implements IBoutiqueContract.IModel { 21 | 22 | @Override 23 | public void getBoutiqueMap(final IBoutiqueContract.IPresenter presenter) { 24 | 25 | 26 | 27 | Map map = new HashMap<>(); 28 | map.put(Constant.USER_AGENT, Constant.USER_AGENT_VALUE); 29 | OkHttpUtil.getInstance().getAsync(Url.MAIN_PAGE, new OkHttpResultCallback() { 30 | @Override 31 | public void onError(Call call, Exception e) { 32 | presenter.showError(e.getMessage()); 33 | } 34 | 35 | @Override 36 | public void onResponse(String msg) { 37 | presenter.setBoutiqueMap((JsoupUtil.getInstance().getBoutiqueApps(msg))); 38 | 39 | 40 | } 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/module/MainModule.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.module; 2 | 3 | 4 | 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import okhttp3.Call; 12 | import piratehat.appstore.Bean.BannerBean; 13 | import piratehat.appstore.config.Constant; 14 | import piratehat.appstore.config.Url; 15 | import piratehat.appstore.contract.IMainContract; 16 | 17 | 18 | import piratehat.appstore.utils.CacheUtil; 19 | 20 | import piratehat.appstore.utils.JsoupUtil; 21 | import piratehat.appstore.utils.OkHttpResultCallback; 22 | import piratehat.appstore.utils.OkHttpUtil; 23 | 24 | /** 25 | * 26 | * Created by PirateHat on 2018/10/27. 27 | */ 28 | 29 | public class MainModule implements IMainContract.IModel { 30 | private static final String TAG = "MainModule"; 31 | 32 | @Override 33 | public void getMainPage(final IMainContract.IPresenter presenter) { 34 | List list ; 35 | if ((list = CacheUtil.getInstance().get(Url.MAIN_PAGE))!=null){ 36 | presenter.setBanner((ArrayList) list); 37 | return ; 38 | } 39 | 40 | Map map = new HashMap<>(); 41 | map.put(Constant.USER_AGENT, Constant.USER_AGENT_VALUE); 42 | OkHttpUtil.getInstance().getAsync(Url.MAIN_PAGE, new OkHttpResultCallback() { 43 | @Override 44 | public void onError(Call call, Exception e) { 45 | presenter.showError(e.getMessage()); 46 | } 47 | 48 | @Override 49 | public void onResponse(String msg) { 50 | 51 | presenter.setBanner((ArrayList) JsoupUtil.getInstance().getBanner(msg)); 52 | CacheUtil.getInstance().put(Url.MAIN_PAGE,JsoupUtil.getInstance().getBanner(msg)); 53 | // presenter.setRankApps((JsoupUtil.getInstance().getRankApps(msg))); 54 | // presenter.setBoutiqueApps(JsoupUtil.getInstance().getBoutiqueApps(msg)); 55 | // DiskCacheManager.getDiskInstance().put(Url.MAIN_PAGE,msg); 56 | 57 | } 58 | 59 | }, map); 60 | } 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/module/OkHttpRequestHandle.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.module; 2 | 3 | import com.shizhefei.mvc.RequestHandle; 4 | 5 | import piratehat.appstore.utils.OkHttpUtil; 6 | 7 | /** 8 | * Created by PirateHat on 2018/11/5. 9 | */ 10 | 11 | public class OkHttpRequestHandle implements RequestHandle { 12 | 13 | 14 | OkHttpRequestHandle() { 15 | super(); 16 | 17 | } 18 | 19 | @Override 20 | public void cancle() { 21 | OkHttpUtil.getInstance().cancelAllRequest(); 22 | } 23 | 24 | @Override 25 | public boolean isRunning() { 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/module/RankModel.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.module; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import okhttp3.Call; 7 | import piratehat.appstore.config.Constant; 8 | import piratehat.appstore.config.Url; 9 | import piratehat.appstore.contract.IRankContract; 10 | import piratehat.appstore.utils.JsoupUtil; 11 | import piratehat.appstore.utils.OkHttpResultCallback; 12 | import piratehat.appstore.utils.OkHttpUtil; 13 | 14 | /** 15 | * Created by PirateHat on 2018/11/23. 16 | */ 17 | 18 | public class RankModel implements IRankContract.IModel { 19 | 20 | @Override 21 | public void getRankMap(final IRankContract.IPresenter presenter) { 22 | Map map = new HashMap<>(); 23 | map.put(Constant.USER_AGENT, Constant.USER_AGENT_VALUE); 24 | OkHttpUtil.getInstance().getAsync(Url.MAIN_PAGE, new OkHttpResultCallback() { 25 | @Override 26 | public void onError(Call call, Exception e) { 27 | presenter.showError(e.getMessage()); 28 | } 29 | 30 | @Override 31 | public void onResponse(String msg) { 32 | 33 | presenter.setRankMap((JsoupUtil.getInstance().getRankApps(msg))); 34 | 35 | 36 | } 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/AppDetailPresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | import piratehat.appstore.Bean.AppDetailBean; 10 | 11 | 12 | import piratehat.appstore.contract.IAppDetailsContract; 13 | import piratehat.appstore.module.AppDetailModel; 14 | 15 | 16 | /** 17 | * Created by PirateHat on 2018/11/20. 18 | */ 19 | 20 | public class AppDetailPresenter implements IAppDetailsContract.IPresenter { 21 | 22 | private IAppDetailsContract.IView mIView; 23 | private IAppDetailsContract.IModel mIModel; 24 | 25 | public AppDetailPresenter(IAppDetailsContract.IView IView) { 26 | mIView = IView; 27 | mIModel = new AppDetailModel(); 28 | } 29 | 30 | @Override 31 | public void setAppInfo(AppDetailBean appInfo) { 32 | mIView.setAppInfo(appInfo); 33 | } 34 | 35 | @Override 36 | public void getAppDetailInfo(String apkName) { 37 | mIModel.getAppDetailInfo(this, apkName); 38 | } 39 | 40 | @Override 41 | public void showError(String msg) { 42 | mIView.showError(msg); 43 | } 44 | 45 | @Override 46 | public void download(String name, String url) { 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/AppPresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | 7 | import piratehat.appstore.Bean.AppBean; 8 | import piratehat.appstore.contract.IAppsContract; 9 | import piratehat.appstore.module.ClassifyModel; 10 | import piratehat.appstore.module.CommonAppsModel; 11 | 12 | /** 13 | * 14 | * Created by PirateHat on 2018/11/3. 15 | */ 16 | 17 | public class AppPresenter implements IAppsContract.IPresenter { 18 | 19 | private IAppsContract.IView mIView; 20 | private IAppsContract.IModel mIModel; 21 | 22 | 23 | public AppPresenter(IAppsContract.IView IView,String category) { 24 | mIView = IView; 25 | mIModel =new CommonAppsModel(category); 26 | } 27 | 28 | 29 | public AppPresenter(IAppsContract.IView IView,int id) { 30 | mIView = IView; 31 | mIModel =new ClassifyModel(id); 32 | } 33 | 34 | 35 | @Override 36 | public void setResult(ArrayList beans) { 37 | if (beans!=null){ 38 | mIView.setResult(beans); 39 | } 40 | 41 | } 42 | 43 | @Override 44 | public void getCategory(String category) { 45 | mIModel.getCategory(this,category); 46 | } 47 | 48 | @Override 49 | public void showError(String msg) { 50 | mIView.showError(msg); 51 | } 52 | 53 | @Override 54 | public IAsyncDataSource getAppsData(String category) { 55 | return mIModel; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/BoutiquePresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import java.util.Map; 4 | 5 | import piratehat.appstore.contract.IBoutiqueContract; 6 | import piratehat.appstore.module.BoutiqueModel; 7 | 8 | /** 9 | * Created by PirateHat on 2018/11/23. 10 | */ 11 | 12 | public class BoutiquePresenter implements IBoutiqueContract.IPresenter { 13 | 14 | private IBoutiqueContract.IView mIView; 15 | private IBoutiqueContract.IModel mIModel; 16 | 17 | public BoutiquePresenter(IBoutiqueContract.IView IView) { 18 | mIView = IView; 19 | mIModel = new BoutiqueModel(); 20 | } 21 | 22 | 23 | 24 | @Override 25 | public void showError(String msg) { 26 | mIView.showError(msg); 27 | } 28 | 29 | @Override 30 | public void setBoutiqueMap(Map map) { 31 | mIView.setBoutiqueMap(map); 32 | } 33 | 34 | @Override 35 | public void getBoutiqueMap() { 36 | mIModel.getBoutiqueMap(this); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/GamePresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | 4 | 5 | import com.shizhefei.mvc.IAsyncDataSource; 6 | 7 | import java.util.ArrayList; 8 | 9 | 10 | import piratehat.appstore.Bean.AppBean; 11 | import piratehat.appstore.contract.IGameContract; 12 | import piratehat.appstore.module.GameModel; 13 | 14 | /** 15 | * Created by PirateHat on 2018/11/13. 16 | */ 17 | 18 | public class GamePresenter implements IGameContract.IPresenter { 19 | 20 | private IGameContract.IView mIView; 21 | private IGameContract.IModel mIModel; 22 | private static final String TAG = "GamePresenter"; 23 | 24 | public GamePresenter(IGameContract.IView IView) { 25 | mIView = IView; 26 | mIModel = new GameModel(); 27 | } 28 | 29 | @Override 30 | public void setAppsList(ArrayList beans) { 31 | 32 | mIView.setAllApps(beans); 33 | } 34 | 35 | @Override 36 | public void getAppsList() { 37 | 38 | mIModel.getAllApps(this); 39 | } 40 | 41 | @Override 42 | public void showError(String msg) { 43 | 44 | } 45 | 46 | @Override 47 | public IAsyncDataSource loadMore() { 48 | 49 | return mIModel; 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/MainPresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import piratehat.appstore.Bean.AppBean; 10 | import piratehat.appstore.Bean.BannerBean; 11 | import piratehat.appstore.contract.IMainContract; 12 | import piratehat.appstore.module.MainAppsModel; 13 | import piratehat.appstore.module.MainModule; 14 | 15 | /** 16 | * 17 | * Created by PirateHat on 2018/10/27. 18 | */ 19 | 20 | public class MainPresenter implements IMainContract.IPresenter { 21 | 22 | private IMainContract.IView mIView; 23 | private IMainContract.IModel mIModel; 24 | 25 | public MainPresenter(IMainContract.IView IView) { 26 | mIView = IView; 27 | mIModel = new MainModule(); 28 | } 29 | 30 | @Override 31 | public void getMainPage() { 32 | mIModel.getMainPage(this); 33 | 34 | } 35 | 36 | @Override 37 | public void setBanner(ArrayList beans) { 38 | ArrayList titles = new ArrayList<>(); 39 | int size = beans.size(); 40 | for (int i = 0; i < size; i++) { 41 | titles.add(beans.get(i).getName()); 42 | } 43 | mIView.setBanner(beans, titles); 44 | } 45 | 46 | @Override 47 | public void setRankApps(Map> beans) { 48 | mIView.setRankApps(beans); 49 | } 50 | 51 | @Override 52 | public void showError(String msg) { 53 | mIView.showError(msg); 54 | } 55 | 56 | @Override 57 | public void setBoutiqueApps(Map> beans) { 58 | mIView.setBoutiqueApps(beans); 59 | } 60 | 61 | @Override 62 | public IAsyncDataSource getRefreshData() { 63 | return new MainAppsModel(this); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/RankPresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import java.util.Map; 4 | 5 | import piratehat.appstore.contract.IRankContract; 6 | import piratehat.appstore.module.RankModel; 7 | 8 | /** 9 | * Created by PirateHat on 2018/11/23. 10 | */ 11 | 12 | public class RankPresenter implements IRankContract.IPresenter { 13 | 14 | private IRankContract.IView mIView; 15 | private IRankContract.IModel mIModel; 16 | 17 | public RankPresenter(IRankContract.IView IView) { 18 | mIView = IView; 19 | mIModel = new RankModel(); 20 | } 21 | 22 | @Override 23 | public void showError(String msg) { 24 | mIView.showError(msg); 25 | } 26 | 27 | @Override 28 | public void setRankMap(Map map) { 29 | mIView.setRankMap(map); 30 | } 31 | 32 | @Override 33 | public void getRankMap() { 34 | mIModel.getRankMap(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/SoftwarePresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | 7 | 8 | import piratehat.appstore.Bean.AppBean; 9 | 10 | import piratehat.appstore.contract.ISoftwareContract; 11 | import piratehat.appstore.module.SoftwareModel; 12 | 13 | /** 14 | * Created by PirateHat on 2018/11/13. 15 | */ 16 | 17 | public class SoftwarePresenter implements ISoftwareContract.IPresenter { 18 | 19 | private ISoftwareContract.IView mIView; 20 | private ISoftwareContract.IModel mIModel; 21 | 22 | public SoftwarePresenter(ISoftwareContract.IView IView) { 23 | mIView = IView; 24 | mIModel = new SoftwareModel(); 25 | } 26 | 27 | @Override 28 | public void setAppsList(ArrayList beans) { 29 | 30 | mIView.setAllApps(beans); 31 | } 32 | 33 | @Override 34 | public void getAppsList() { 35 | mIModel.getAllApps(this); 36 | } 37 | 38 | @Override 39 | public void showError(String msg) { 40 | 41 | } 42 | 43 | @Override 44 | public IAsyncDataSource loadMore() { 45 | return mIModel; 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/presenter/TencentPresenter.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.presenter; 2 | 3 | import com.shizhefei.mvc.IAsyncDataSource; 4 | 5 | import java.util.ArrayList; 6 | 7 | import piratehat.appstore.Bean.AppBean; 8 | import piratehat.appstore.contract.ITencentContract; 9 | import piratehat.appstore.module.TencentModel; 10 | 11 | /** 12 | * Created by PirateHat on 2018/11/5. 13 | */ 14 | 15 | public class TencentPresenter implements ITencentContract.IPresenter { 16 | private ITencentContract.IView mIView; 17 | private ITencentContract.IModel mIModel; 18 | 19 | public TencentPresenter(ITencentContract.IView IView) { 20 | mIView = IView; 21 | mIModel = new TencentModel(); 22 | } 23 | 24 | @Override 25 | public void setAppsList(ArrayList beans) { 26 | mIView.setAppsList(beans); 27 | } 28 | 29 | @Override 30 | public void showError(String msg) { 31 | 32 | } 33 | 34 | @Override 35 | public void getAppsList() { 36 | mIModel.getAppsList(this); 37 | } 38 | 39 | @Override 40 | public IAsyncDataSource loadMore() { 41 | return mIModel; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/ui/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.ui; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.Menu; 9 | import android.view.MenuItem; 10 | 11 | import butterknife.ButterKnife; 12 | import piratehat.appstore.R; 13 | 14 | /** 15 | * 16 | * Created by PirateHat on 2018/11/3. 17 | */ 18 | 19 | public abstract class BaseActivity extends AppCompatActivity { 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(setResId()); 25 | ButterKnife.bind(this); 26 | initData(getIntent().getBundleExtra("bundle")); 27 | initView(); 28 | initListener(); 29 | 30 | } 31 | 32 | 33 | @Override 34 | public boolean onCreateOptionsMenu(Menu menu) { 35 | getMenuInflater().inflate(R.menu.menu_tools, menu); 36 | return true; 37 | } 38 | 39 | @Override 40 | public boolean onOptionsItemSelected(MenuItem item) { 41 | 42 | switch (item.getItemId()) { 43 | case R.id.item_search: 44 | 45 | break; 46 | case R.id.item_download: 47 | 48 | break; 49 | case android.R.id.home: { 50 | finish(); 51 | 52 | } 53 | 54 | } 55 | return false; 56 | 57 | } 58 | protected abstract int setResId(); 59 | protected abstract void initView(); 60 | protected abstract void initData(Bundle bundle); 61 | protected abstract void initListener(); 62 | 63 | public static void actionStart(Context context,Class clazz){ 64 | Intent intent = new Intent(context,clazz); 65 | context.startActivity(intent); 66 | } 67 | public static void actionStart(Context context,Class clazz,Bundle bundle){ 68 | Intent intent = new Intent(context,clazz); 69 | intent.putExtra("bundle", bundle); 70 | context.startActivity(intent); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/ui/DownloadManagerActivity.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.ui; 2 | 3 | 4 | import android.content.BroadcastReceiver; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.IntentFilter; 8 | import android.os.Bundle; 9 | import android.support.v7.app.ActionBar; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.support.v7.widget.Toolbar; 12 | 13 | import java.util.HashMap; 14 | import java.util.List; 15 | 16 | import butterknife.BindView; 17 | import piratehat.appstore.Bean.AppDownloadInfo; 18 | import piratehat.appstore.R; 19 | import piratehat.appstore.adapter.DownloadAppAdapter; 20 | 21 | public class DownloadManagerActivity extends BaseActivity { 22 | 23 | @BindView(R.id.tool_bar) 24 | Toolbar mToolBar; 25 | @BindView(R.id.rv_download_apps) 26 | RecyclerView mRvDownloadApps; 27 | private DownloadAppAdapter mAdapter; 28 | private List mInfos; 29 | 30 | @Override 31 | protected int setResId() { 32 | return R.layout.activity_download_manager; 33 | } 34 | 35 | @Override 36 | protected void initView() { 37 | setSupportActionBar(mToolBar); 38 | ActionBar actionBar = getSupportActionBar(); 39 | assert actionBar != null; 40 | actionBar.setDisplayHomeAsUpEnabled(true); 41 | actionBar.setDisplayShowTitleEnabled(false); 42 | mToolBar.setTitle("下载管理"); 43 | 44 | } 45 | 46 | @Override 47 | protected void initData(Bundle bundle) { 48 | mAdapter = new DownloadAppAdapter(mInfos,this); 49 | mRvDownloadApps.setAdapter(mAdapter); 50 | 51 | } 52 | 53 | @Override 54 | protected void initListener() { 55 | IntentFilter filter = new IntentFilter(); 56 | HashMap map = DownloadUtil.getInstance().getMap(); 57 | for (String key : map.keySet()) { 58 | filter.addAction(key); 59 | } 60 | registerReceiver(receiver, filter);// 61 | } 62 | 63 | private BroadcastReceiver receiver = new BroadcastReceiver() { 64 | @Override 65 | public void onReceive(Context context, Intent intent) { 66 | if (null != intent) { 67 | HashMap map = DownloadUtil.getInstance().getMap(); 68 | for (String key : map.keySet()) { 69 | 70 | } 71 | } 72 | 73 | } 74 | }; 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/ui/DownloadUtil.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.ui; 2 | 3 | import java.util.HashMap; 4 | 5 | import static piratehat.appstore.config.Download.State.NEW; 6 | 7 | /** 8 | * 9 | * Created by PirateHat on 2018/11/21. 10 | */ 11 | 12 | public class DownloadUtil { 13 | 14 | 15 | private static DownloadUtil sDownlaod; 16 | 17 | 18 | 19 | private HashMap mMap; 20 | 21 | private DownloadUtil() { 22 | mMap = new HashMap<>(); 23 | } 24 | 25 | 26 | public static DownloadUtil getInstance() { 27 | if (sDownlaod == null) { 28 | sDownlaod = new DownloadUtil(); 29 | } 30 | return sDownlaod; 31 | } 32 | 33 | public State getState(String url) { 34 | State state = mMap.get(url); 35 | if (state==null){ 36 | state = new State(); 37 | state.setState(NEW); 38 | return state; 39 | } 40 | return state; 41 | } 42 | 43 | public HashMap getMap() { 44 | return mMap; 45 | } 46 | 47 | public void setState(int state, String url){ 48 | State state1 = mMap.get(url); 49 | if (state1!=null){ 50 | state1.setState(state); 51 | } 52 | mMap.put(url,state1); 53 | } 54 | 55 | 56 | 57 | 58 | class State { 59 | private int mState; 60 | 61 | public int getState() { 62 | return mState; 63 | } 64 | 65 | public void setState(int state) { 66 | mState = state; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/BottomNavigationViewHelper.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.support.design.internal.BottomNavigationItemView; 5 | import android.support.design.internal.BottomNavigationMenuView; 6 | import android.support.design.widget.BottomNavigationView; 7 | 8 | import java.lang.reflect.Field; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/10/27. 13 | */ 14 | 15 | public class BottomNavigationViewHelper { 16 | @SuppressLint("RestrictedApi") 17 | public static void disableShiftMode(BottomNavigationView navigationView) { 18 | BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0); 19 | try { 20 | Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); 21 | shiftingMode.setAccessible(true); 22 | shiftingMode.setBoolean(menuView, false); 23 | shiftingMode.setAccessible(false); 24 | 25 | for (int i = 0; i < menuView.getChildCount(); i++) { 26 | BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i); 27 | itemView.setShiftingMode(false); 28 | itemView.setChecked(itemView.getItemData().isChecked()); 29 | } 30 | 31 | } catch (NoSuchFieldException | IllegalAccessException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/CloseQuicklyUtil.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | import java.io.Closeable; 4 | import java.io.IOException; 5 | 6 | /** 7 | * 8 | * Created by PirateHat on 2018/11/22. 9 | */ 10 | 11 | public class CloseQuicklyUtil { 12 | 13 | public static void close(Closeable closeable){ 14 | if (closeable!=null){ 15 | try { 16 | closeable.close(); 17 | } catch (IOException e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/GlideImageLoader.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | import android.content.Context; 4 | import android.widget.ImageView; 5 | 6 | import com.bumptech.glide.Glide; 7 | import com.youth.banner.loader.ImageLoader; 8 | 9 | import piratehat.appstore.Bean.BannerBean; 10 | 11 | /** 12 | * 13 | * Created by PirateHat on 2018/10/27. 14 | */ 15 | 16 | public class GlideImageLoader extends ImageLoader { 17 | @Override 18 | public void displayImage(Context context, Object path, ImageView imageView) { 19 | Glide.with(context).load(((BannerBean)path).getImageUrl()).into(imageView); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/OkHttpCookieJar.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import okhttp3.Cookie; 9 | import okhttp3.CookieJar; 10 | import okhttp3.HttpUrl; 11 | 12 | public class OkHttpCookieJar implements CookieJar { 13 | private static List sCookies; 14 | 15 | @Override 16 | public void saveFromResponse(HttpUrl url, List cookies) { 17 | sCookies = cookies; 18 | } 19 | 20 | @Override 21 | public List loadForRequest(HttpUrl url) { 22 | if (null != sCookies){ 23 | return sCookies; 24 | }else { 25 | return new ArrayList<>(); 26 | } 27 | } 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/OkHttpResultCallback.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | 4 | import okhttp3.Call; 5 | 6 | public interface OkHttpResultCallback { 7 | 8 | void onError(Call call, Exception e); 9 | 10 | void onResponse(String msg); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/SecretUtil.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | import android.provider.SyncStateContract; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | import java.security.MessageDigest; 7 | import java.security.NoSuchAlgorithmException; 8 | 9 | import piratehat.appstore.config.Constant; 10 | 11 | /** 12 | * 13 | * Created by PirateHat on 2018/11/22. 14 | */ 15 | 16 | public class SecretUtil { 17 | 18 | /** 19 | * 传入字符串参数,返回MD5加密结果(小写) 20 | * 21 | * @param value 待加密的字符串 22 | * @return 加密结果 23 | */ 24 | public static String getMD5Result(String value) { 25 | try { 26 | MessageDigest md = MessageDigest.getInstance("MD5"); 27 | md.update(value.getBytes("UTF-8")); 28 | byte[] result = md.digest(); 29 | return getString(result); 30 | } catch (NoSuchAlgorithmException e) { 31 | e.printStackTrace(); 32 | return Constant.NOSUCHALGORITHM; 33 | } catch (UnsupportedEncodingException e) { 34 | e.printStackTrace(); 35 | return Constant.UNSUPPENCODING; 36 | } 37 | } 38 | 39 | private static String getString(byte[] result) { 40 | StringBuilder sb = new StringBuilder(); 41 | for (byte b : result) { 42 | int i = b & 0xff; 43 | if (i <= 0xf) { 44 | sb.append(0); 45 | } 46 | sb.append(Integer.toHexString(i)); 47 | } 48 | return sb.toString().toLowerCase(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/utils/UnitUtil.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.utils; 2 | 3 | import android.annotation.SuppressLint; 4 | 5 | /** 6 | * 7 | * Created by PirateHat on 2018/10/28. 8 | */ 9 | 10 | public class UnitUtil { 11 | private static final String BILLION_DOWNLOAD ="亿次下载"; 12 | private static final String MILLION_DOWNLOAD = "万次下载"; 13 | private static final String DOWNLOAD = "次下载"; 14 | 15 | 16 | 17 | public static String converse(int i){ 18 | if (i<10000){ 19 | return i+DOWNLOAD; 20 | } 21 | if (i<100000000){ 22 | return i/10000 + MILLION_DOWNLOAD; 23 | } 24 | return i/100000000 +BILLION_DOWNLOAD; 25 | } 26 | 27 | public static String converse(long i){ 28 | if (i<10000){ 29 | return i+DOWNLOAD; 30 | } 31 | if (i<100000000){ 32 | return i/10000 + MILLION_DOWNLOAD; 33 | } 34 | return i/100000000 +BILLION_DOWNLOAD; 35 | } 36 | @SuppressLint("DefaultLocale") 37 | public static String convertFileSize(long size) { 38 | long kb = 1024; 39 | long mb = kb * 1024; 40 | long gb = mb * 1024; 41 | 42 | if (size >= gb) { 43 | return String.format("%.1f GB", (float) size / gb); 44 | } else if (size >= mb) { 45 | float f = (float) size / mb; 46 | return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); 47 | } else if (size >= kb) { 48 | float f = (float) size / kb; 49 | return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); 50 | } else 51 | return String.format("%d B", size); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/appstore/widget/NoScrollViewPager.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore.widget; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.view.ViewPager; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | 10 | /** 11 | * 12 | * Created by PirateHat on 2018/11/13. 13 | */ 14 | 15 | public class NoScrollViewPager extends ViewPager { 16 | private boolean isScroll; 17 | 18 | public NoScrollViewPager(Context context) { 19 | super(context); 20 | } 21 | 22 | public NoScrollViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | 27 | @Override 28 | public boolean dispatchTouchEvent(MotionEvent ev) { 29 | return super.dispatchTouchEvent(ev); 30 | } 31 | 32 | /** 33 | * 是否拦截 34 | * 拦截:会走到自己的onTouchEvent方法里面来 35 | * 不拦截:事件传递给子孩子 36 | */ 37 | @Override 38 | public boolean onInterceptTouchEvent(MotionEvent ev) { 39 | // return false;//可行,不拦截事件, 40 | // return true;//不行,孩子无法处理事件 41 | //return super.onInterceptTouchEvent(ev);//不行,会有细微移动 42 | if (isScroll) { 43 | return super.onInterceptTouchEvent(ev); 44 | } else { 45 | return false; 46 | } 47 | } 48 | 49 | /** 50 | * 是否消费事件 51 | * 消费:事件就结束 52 | * 不消费:往父控件传 53 | */ 54 | @Override 55 | public boolean onTouchEvent(MotionEvent ev) { 56 | //return false;// 可行,不消费,传给父控件 57 | //return true;// 可行,消费,拦截事件 58 | //super.onTouchEvent(ev); //不行, 59 | //虽然onInterceptTouchEvent中拦截了, 60 | //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法. 61 | if (isScroll) { 62 | return super.onTouchEvent(ev); 63 | } else { 64 | return true;// 可行,消费,拦截事件 65 | } 66 | } 67 | 68 | public void setScroll(boolean scroll) { 69 | isScroll = scroll; 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/BridgesInterceptor.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | /** 4 | * Created by PirateHat on 2019/2/19. 5 | */ 6 | 7 | public class BridgesInterceptor implements Interceptor { 8 | private final boolean DEBUG = true; 9 | 10 | @Override 11 | public Response intercept(Chain chain) { 12 | 13 | Request request = chain.request(); 14 | request.addHeader("Host: " + request.host()) 15 | .addHeader("Connection: keep-alive") 16 | .addHeader("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"); 17 | // .addHeader("Accept-Encoding: gzip"); 18 | 19 | if (DEBUG) { 20 | System.out.println(request.headers().toString()); 21 | } 22 | Response response = chain.proceed(request); 23 | 24 | 25 | return response; 26 | } 27 | 28 | 29 | } 30 | //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36 31 | //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Call.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * 7 | * Created by PirateHat on 2019/2/18. 8 | */ 9 | 10 | public interface Call { 11 | 12 | Request request(); 13 | 14 | /** 15 | * 同步的请求 16 | * @return Response 17 | */ 18 | Response execute() throws IOException; 19 | 20 | 21 | void enqueue(Callback callback); 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Callback.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | /** 4 | * 5 | * Created by PirateHat on 2019/2/18. 6 | */ 7 | 8 | public interface Callback { 9 | 10 | void onFailure(Call call,Exception e); 11 | 12 | void onResponse(Call call,Response response); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/ConnectInterceptor.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | /** 4 | * Created by PirateHat on 2019/2/19. 5 | */ 6 | 7 | public class ConnectInterceptor implements Interceptor { 8 | 9 | 10 | @Override 11 | public Response intercept(Chain chain) { 12 | Request request = chain.request(); 13 | Response response = null; 14 | RealConnection realConnection = new RealConnection(request.protocol(), chain.httpClient(), request.host()); 15 | response = realConnection.connect(request); 16 | return response; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Interceptor.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | /** 4 | * 5 | * Created by PirateHat on 2019/2/18. 6 | */ 7 | 8 | public interface Interceptor { 9 | 10 | Response intercept(Chain chain); 11 | 12 | 13 | interface Chain{ 14 | Request request(); 15 | 16 | Response proceed(Request request); 17 | 18 | HttpClient httpClient(); 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/NameRunnable.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | /** 4 | * Created by PirateHat on 2019/2/18. 5 | */ 6 | 7 | public abstract class NameRunnable implements Runnable { 8 | 9 | private String mName; 10 | public NameRunnable(String name) { 11 | this.mName = name; 12 | } 13 | 14 | @Override 15 | public void run() { 16 | Thread thread = Thread.currentThread(); 17 | String oldName = thread.getName(); 18 | thread.setName(mName); 19 | execute(); 20 | thread.setName(oldName); 21 | } 22 | 23 | 24 | public abstract void execute(); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Protocol.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | 4 | 5 | /** 6 | * 7 | * Created by PirateHat on 2019/2/18. 8 | */ 9 | 10 | public enum Protocol { 11 | HTTP("http"), 12 | HTTPS("https"); 13 | 14 | private final String protocol; 15 | 16 | Protocol(String protocol) { 17 | this.protocol = protocol; 18 | } 19 | 20 | 21 | @Override 22 | public String toString() { 23 | return protocol; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/RealCall.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * Created by PirateHat on 2019/2/18. 9 | */ 10 | 11 | public class RealCall implements Call { 12 | private Request mRequest; 13 | 14 | private HttpClient mHttpClient; 15 | 16 | public RealCall(HttpClient httpClient, Request request) { 17 | mHttpClient = httpClient; 18 | mRequest = request; 19 | } 20 | 21 | @Override 22 | public Request request() { 23 | return mRequest; 24 | } 25 | 26 | 27 | /** 28 | * 同步请求 29 | * 30 | * @return Response 31 | */ 32 | @Override 33 | public Response execute() throws IOException { 34 | mHttpClient.dispatcher.execute(this); 35 | Response response = getResponseWithInterceptorChain(); 36 | if (response == null) { 37 | throw new IOException("Cancel!"); 38 | } 39 | mHttpClient.dispatcher.finish(this); 40 | return response; 41 | } 42 | 43 | /** 44 | * 异步的请求 45 | * 46 | * @param callback 回调 47 | */ 48 | @Override 49 | public void enqueue(Callback callback) { 50 | mHttpClient.dispatcher.enqueue(new AsyncCall(callback)); 51 | } 52 | 53 | final class AsyncCall extends NameRunnable { 54 | private Callback mCallback; 55 | 56 | public AsyncCall(Callback callback) { 57 | super(mRequest.url()); 58 | mCallback = callback; 59 | } 60 | 61 | @Override 62 | public void execute() { 63 | Response response = getResponseWithInterceptorChain(); 64 | if (response.isCanceled()){ 65 | mCallback.onFailure(RealCall.this,response.getException()); 66 | }else { 67 | mCallback.onResponse(RealCall.this,response); 68 | } 69 | mHttpClient.dispatcher.finish(this); 70 | } 71 | } 72 | 73 | private Response getResponseWithInterceptorChain() { 74 | List interceptors = new ArrayList<>(); 75 | interceptors.addAll(mHttpClient.interceptors); 76 | interceptors.add(new RetryInterceptor()); 77 | interceptors.add(new BridgesInterceptor()); 78 | interceptors.add(new ConnectInterceptor()); 79 | Interceptor.Chain chain = new RealInterceptorChain(mHttpClient,mRequest,interceptors,0); 80 | return chain.proceed(mRequest); 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/RealInterceptorChain.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by PirateHat on 2019/2/18. 7 | */ 8 | 9 | public class RealInterceptorChain implements Interceptor.Chain { 10 | 11 | private Request mRequest; 12 | private List mInterceptors; 13 | private final int mIndex ; 14 | private HttpClient mHttpClient; 15 | 16 | public RealInterceptorChain(HttpClient httpClient,Request request, List interceptors,int index) { 17 | mRequest = request; 18 | mInterceptors = interceptors; 19 | mIndex = index; 20 | mHttpClient = httpClient; 21 | } 22 | 23 | @Override 24 | public Request request() { 25 | return mRequest; 26 | } 27 | 28 | @Override 29 | public Response proceed(Request request) { 30 | 31 | RealInterceptorChain next = new RealInterceptorChain(mHttpClient,mRequest,mInterceptors,mIndex+1); 32 | Interceptor interceptor = mInterceptors.get(mIndex); 33 | Response response = interceptor.intercept(next); 34 | if (response == null){ 35 | throw new NullPointerException("interceptor " + interceptor + "return null!"); 36 | } 37 | return response; 38 | } 39 | 40 | @Override 41 | public HttpClient httpClient() { 42 | return mHttpClient; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Request.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.net.URI; 4 | import java.net.URISyntaxException; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * Created by PirateHat on 2019/2/18. 11 | */ 12 | 13 | public class Request { 14 | private final String mUrl; 15 | private final String mPath; 16 | private final String mHost; 17 | private final ArrayList mHeaders; 18 | private final Protocol mProtocol; 19 | private URI mURI; 20 | volatile boolean mCanceled; 21 | private boolean mIsHeader; 22 | 23 | 24 | public Request(String url) { 25 | System.out.println(url); 26 | mUrl = url; 27 | mHeaders = new ArrayList<>(); 28 | try { 29 | mURI = new URI(url); 30 | } catch (URISyntaxException e) { 31 | e.printStackTrace(); 32 | } 33 | mPath = mURI.getPath(); 34 | mHost = mURI.getHost(); 35 | mProtocol = mURI.getScheme()==null?Protocol.HTTPS:mURI.getScheme().equals(Protocol.HTTP.toString()) ? Protocol.HTTP : Protocol.HTTPS; 36 | addHeader(this.method() + " " + this.path() + " HTTP/1.1"); 37 | } 38 | 39 | public boolean isHeader() { 40 | return mIsHeader; 41 | } 42 | 43 | public void setHeader(boolean header) { 44 | mIsHeader = header; 45 | } 46 | 47 | public Request addHeader(String header) { 48 | mHeaders.add(header); 49 | return this; 50 | } 51 | 52 | public List headers() { 53 | return mHeaders; 54 | } 55 | 56 | public String url() { 57 | return mUrl; 58 | } 59 | 60 | public String method() { 61 | return "GET"; 62 | } 63 | 64 | public String path() { 65 | return mPath; 66 | } 67 | 68 | public String host() { 69 | return mHost; 70 | } 71 | 72 | public Protocol protocol() { 73 | return mProtocol; 74 | } 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/Response.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | 6 | /** 7 | * Created by PirateHat on 2019/2/18. 8 | */ 9 | 10 | public class Response { 11 | private String mResultString; 12 | private HashMap mHeaders; 13 | public int mStatus; 14 | private boolean mCanceled ; 15 | private IOException mException; 16 | private byte[] mByteArray; 17 | private long mContentLength; 18 | 19 | 20 | @Override 21 | public String toString() { 22 | return "Response{" + 23 | "mResultString='" + mResultString + '\'' + 24 | '}'; 25 | } 26 | 27 | 28 | 29 | public void setResultString(String resultString) { 30 | mResultString = resultString; 31 | } 32 | 33 | public void setHeaders(HashMap headers) { 34 | mHeaders = headers; 35 | if (mHeaders!=null){ 36 | String title = mHeaders.get(""); 37 | String[] parts = title.split(" "); 38 | mStatus = Integer.valueOf(parts[1]); 39 | if (mHeaders.get("Content-Length")!=null){ 40 | mContentLength = Long.valueOf(mHeaders.get("Content-Length")); 41 | }else { 42 | mContentLength =0; 43 | } 44 | } 45 | } 46 | 47 | public byte[] getByteArray() { 48 | return mByteArray; 49 | } 50 | 51 | public void setByteArray(byte[] byteArray) { 52 | mByteArray = byteArray; 53 | } 54 | 55 | public boolean isCanceled() { 56 | return mCanceled; 57 | } 58 | 59 | public void setCanceled(boolean canceled) { 60 | mCanceled = canceled; 61 | } 62 | 63 | public void setException(IOException exception) { 64 | mException = exception; 65 | } 66 | 67 | public IOException getException() { 68 | return mException; 69 | } 70 | 71 | public HashMap getHeaders() { 72 | return mHeaders; 73 | } 74 | 75 | public long getContentLength() { 76 | return mContentLength; 77 | } 78 | 79 | public static final int OK = 200; 80 | public static final int BAD_REQUEST = 400; 81 | public static final int FORRBIDDEN = 404; 82 | public static final int MOVED_TEMPORARILY = 302; 83 | 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/httpClient/RetryInterceptor.java: -------------------------------------------------------------------------------- 1 | package piratehat.httpClient; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * Created by PirateHat on 2019/2/19. 8 | */ 9 | 10 | public class RetryInterceptor implements Interceptor { 11 | 12 | @Override 13 | public Response intercept(Chain chain) { 14 | Request request = chain.request(); 15 | Response response = chain.proceed(request); 16 | while (!response.isCanceled() && response.mStatus == Response.MOVED_TEMPORARILY){ 17 | HashMap headers = response.getHeaders(); 18 | for (String key:headers.keySet()) { 19 | if (key.equals("Location")){ 20 | request = new Request(headers.get(key)); 21 | break; 22 | } 23 | } 24 | response = chain.proceed(request); 25 | } 26 | 27 | return response; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/BitmapDecoder.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | /** 7 | * Created by PirateHat on 2019/2/21. 8 | */ 9 | 10 | public abstract class BitmapDecoder { 11 | public Bitmap decodeBitmap(int width, int height) { 12 | BitmapFactory.Options options = new BitmapFactory.Options(); 13 | options.inJustDecodeBounds = true; 14 | //从文件中读取 Bitmap 15 | decodeBitmapWithOption(options); 16 | 17 | //计算压缩比例 18 | calculateSampleSizeWithOption(options,width,height); 19 | 20 | 21 | options.inJustDecodeBounds = false; 22 | 23 | //再一次读取时进行压缩 24 | return decodeBitmapWithOption(options); 25 | } 26 | 27 | public abstract Bitmap decodeBitmapWithOption(BitmapFactory.Options options); 28 | 29 | public void calculateSampleSizeWithOption(BitmapFactory.Options options, int reqWidth, int reqHeight) { 30 | int width = options.outWidth; 31 | int height = options.outHeight; 32 | 33 | int inSampleSize = 1; 34 | 35 | if (width > reqWidth || height > reqHeight) { 36 | //宽高的缩放比例 37 | 38 | //舍入取整 39 | int heightRatio = Math.round((float) height / (float) reqHeight); 40 | int widthRatio = Math.round((float) width / (float) reqWidth); 41 | inSampleSize = Math.min(widthRatio, heightRatio); 42 | } 43 | options.inSampleSize = inSampleSize; 44 | options.inPreferredConfig = Bitmap.Config.RGB_565; 45 | 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/MD5Utils.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | import android.util.Log; 4 | 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | public class MD5Utils { 9 | 10 | private static MessageDigest digest; 11 | 12 | static { 13 | try { 14 | digest = MessageDigest.getInstance("MD5"); 15 | } catch (NoSuchAlgorithmException e) { 16 | e.printStackTrace(); 17 | Log.d("jason", "md5 算法不支持!"); 18 | } 19 | } 20 | 21 | /** 22 | * MD5加密 23 | * @param key 24 | * @return 25 | */ 26 | public static String toMD5(String key) { 27 | if (digest == null) { 28 | return String.valueOf(key.hashCode()); 29 | } 30 | //更新字节 31 | digest.update(key.getBytes()); 32 | //获取最终的摘要 十进制的 12345678/ABCD1245 33 | return convert2HexString(digest.digest()); 34 | } 35 | 36 | /** 37 | * 转为16进制字符串 38 | * @param bytes 39 | * @return 40 | */ 41 | private static String convert2HexString(byte[] bytes) { 42 | StringBuffer sb = new StringBuffer(); 43 | for (byte b : bytes) { 44 | //->8->08 45 | String hex = Integer.toHexString(0xFF & b); 46 | if (hex.length() == 1) { 47 | sb.append('0'); 48 | } 49 | sb.append(hex); 50 | } 51 | return sb.toString(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/Picture.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | 4 | import android.graphics.Bitmap; 5 | import android.widget.ImageView; 6 | 7 | import piratehat.picture.cache.DoubleCache; 8 | 9 | import piratehat.picture.config.*; 10 | import piratehat.picture.loader.policy.ReverseLoaderPolicy; 11 | 12 | 13 | /** 14 | * Created by PirateHat on 2019/2/21. 15 | */ 16 | 17 | public class Picture { 18 | private volatile static Picture INSTANCE; 19 | private PictureConfig mPictureConfig; 20 | private RequestDispatcher mDispatcher; 21 | 22 | public Picture(PictureConfig pictureConfig) { 23 | if (pictureConfig!=null){ 24 | mPictureConfig = pictureConfig; 25 | }else { 26 | mPictureConfig = new PictureConfig.Builder() 27 | .setBitmapCache(new DoubleCache()) 28 | .setLoadPolicy(new ReverseLoaderPolicy()) 29 | .build(); 30 | } 31 | mDispatcher = new RequestDispatcher(); 32 | } 33 | 34 | public static Picture getInstance(PictureConfig config){ 35 | if (INSTANCE == null){ 36 | synchronized (Picture.class){ 37 | if (INSTANCE == null){ 38 | INSTANCE = new Picture(config); 39 | } 40 | } 41 | } 42 | return INSTANCE; 43 | } 44 | 45 | public static Picture getInstance(){ 46 | return getInstance(null); 47 | } 48 | 49 | 50 | public PictureConfig getPictureConfig() { 51 | return mPictureConfig; 52 | } 53 | 54 | public void display(ImageView imageView, String url) { 55 | display(imageView, url, null, null); 56 | } 57 | 58 | public void display(ImageView imageView, String url, CallBack callback,DisplayConfig config) { 59 | BitmapRequest request = new BitmapRequest(url,imageView,callback,config); 60 | mDispatcher.enqueue(request); 61 | 62 | } 63 | 64 | 65 | public interface CallBack{ 66 | 67 | void onSuccess(Bitmap bitmap,String imageUrl); 68 | 69 | } 70 | 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/RequestDispatcher.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.widget.ImageView; 5 | 6 | import java.util.concurrent.BlockingQueue; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.PriorityBlockingQueue; 9 | import java.util.concurrent.SynchronousQueue; 10 | import java.util.concurrent.ThreadFactory; 11 | import java.util.concurrent.ThreadPoolExecutor; 12 | import java.util.concurrent.TimeUnit; 13 | import java.util.concurrent.atomic.AtomicInteger; 14 | 15 | 16 | 17 | /** 18 | * 19 | * Created by PirateHat on 2019/2/21. 20 | */ 21 | 22 | public class RequestDispatcher { 23 | 24 | private static final boolean DEBUG = true; 25 | private ExecutorService mExecutorService; 26 | private AtomicInteger mInteger ; 27 | public RequestDispatcher() { 28 | mInteger = new AtomicInteger(0); 29 | mExecutorService = new ThreadPoolExecutor( 30 | Runtime.getRuntime().availableProcessors() 31 | , Integer.MAX_VALUE, 60, 32 | TimeUnit.SECONDS, new PriorityBlockingQueue()); 33 | } 34 | 35 | public void enqueue(BitmapRequest request){ 36 | request.setSerialNo(mInteger.getAndDecrement()); 37 | if (request.getDisplayConfig() != null 38 | && request.getDisplayConfig().PLACE_HOLDRE != -1) { 39 | ImageView imageView = request.getImageView(); 40 | if (imageView != null && imageView.getTag().equals(request.getImageUrl())) { 41 | imageView.setImageResource(request.getDisplayConfig().PLACE_HOLDRE); 42 | 43 | } 44 | } 45 | mExecutorService.execute(new RequestRunnable(request)); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/RequestRunnable.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | 4 | import piratehat.picture.loader.ILoader; 5 | import piratehat.picture.loader.LoaderManager; 6 | 7 | /** 8 | * 9 | * Created by PirateHat on 2019/2/21. 10 | */ 11 | 12 | public class RequestRunnable implements Runnable { 13 | 14 | private BitmapRequest mBitmapRequest; 15 | 16 | public RequestRunnable(BitmapRequest request) { 17 | mBitmapRequest = request; 18 | } 19 | 20 | @Override 21 | public void run() { 22 | if (mBitmapRequest.isCancel()) { 23 | return; 24 | } 25 | ILoader loader = LoaderManager.getInstance().getLoaderByType(Util.parseURL(mBitmapRequest.getImageUrl())); 26 | loader.loadImage(mBitmapRequest); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/Util.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture; 2 | 3 | /** 4 | * Created by PirateHat on 2019/2/21. 5 | */ 6 | 7 | public class Util { 8 | // public static File getCache(String unique) { 9 | //// File file = new File(Environment.getExternalStorageDirectory(), "image"); 10 | //// if (!file.exists()) { 11 | //// file.mkdir(); 12 | //// } 13 | //// return new File(file, unique); 14 | // 15 | // } 16 | // public static File getDir() { 17 | // if (mkdirs != null && mkdirs.exists()) { 18 | // return mkdirs; 19 | // } 20 | // 21 | // mkdirs = new File(mCache, "download"); 22 | // if (!mkdirs.exists()) { 23 | // mkdirs.mkdirs(); 24 | // } 25 | // return mkdirs; 26 | // } 27 | 28 | public static String parseURL(String imageURL) { 29 | if (imageURL.contains("://")) { 30 | return imageURL.split("://")[0]; 31 | } 32 | 33 | // L.e("不支持的URL:" + imageURL); 34 | return " "; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/cache/DiskCache.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.cache; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | 6 | import java.io.IOException; 7 | 8 | import piratehat.appstore.app.App; 9 | import piratehat.picture.BitmapRequest; 10 | import piratehat.picture.cache.DiskLruCache.DiskLruCache.DiskLruCacheManager; 11 | 12 | /** 13 | * Created by PirateHat on 2019/2/21. 14 | */ 15 | 16 | public class DiskCache implements IBitmapCache { 17 | private static final String IMAGE_DISK_NAME = "image_cache"; 18 | private DiskLruCacheManager mDiskLruCacheManager; 19 | 20 | public DiskCache() { 21 | try { 22 | mDiskLruCacheManager = new DiskLruCacheManager(App.getContext(),IMAGE_DISK_NAME,1024); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | @Override 29 | public void put(BitmapRequest request, Bitmap bitmap) { 30 | mDiskLruCacheManager.put(request.getMD5CacheKey(),bitmap); 31 | } 32 | 33 | @Override 34 | public Bitmap get(BitmapRequest request) { 35 | return mDiskLruCacheManager.getAsBitmap(request.getMD5CacheKey()); 36 | } 37 | 38 | @Override 39 | public void remove(BitmapRequest request) { 40 | try { 41 | mDiskLruCacheManager.getDiskLruCache().remove(request.getMD5CacheKey()); 42 | } catch (IOException e) { 43 | e.printStackTrace(); 44 | } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/cache/DoubleCache.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.cache; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import piratehat.picture.BitmapRequest; 6 | 7 | /** 8 | * 9 | * Created by PirateHat on 2019/2/21. 10 | */ 11 | 12 | public class DoubleCache implements IBitmapCache { 13 | private MemoryCache mMemoryCache; 14 | private DiskCache mDiskCache; 15 | 16 | public DoubleCache() { 17 | mMemoryCache = new MemoryCache(); 18 | mDiskCache = new DiskCache(); 19 | } 20 | 21 | @Override 22 | public void put(BitmapRequest request, Bitmap bitmap) { 23 | mMemoryCache.put(request, bitmap); 24 | mDiskCache.put(request, bitmap); 25 | } 26 | 27 | @Override 28 | public Bitmap get(BitmapRequest request) { 29 | //先从内存中读取 30 | Bitmap bitmap = mMemoryCache.get(request); 31 | if (bitmap != null) { 32 | return bitmap; 33 | } 34 | //没有就从磁盘中获取 35 | bitmap = mDiskCache.get(request); 36 | if (bitmap != null) { 37 | //加入缓存 38 | mMemoryCache.put(request, bitmap); 39 | return bitmap; 40 | } 41 | 42 | return null; 43 | 44 | } 45 | 46 | @Override 47 | public void remove(BitmapRequest request) { 48 | mMemoryCache.remove(request); 49 | mDiskCache.remove(request); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/cache/IBitmapCache.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.cache; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import piratehat.picture.BitmapRequest; 6 | 7 | /** 8 | * Created by PirateHat on 2019/2/21. 9 | */ 10 | 11 | public interface IBitmapCache { 12 | 13 | /** 14 | * 添加缓存 15 | * @param request 请求 16 | * @param bitmap 图片 17 | */ 18 | void put(BitmapRequest request, Bitmap bitmap); 19 | 20 | 21 | /** 22 | * 从缓存中获取 23 | * @param request 请求 24 | */ 25 | Bitmap get(BitmapRequest request); 26 | 27 | 28 | /** 29 | * 移除缓存 30 | * @param request 请求 31 | */ 32 | void remove(BitmapRequest request); 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/cache/MemoryCache.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.cache; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.IBinder; 5 | import android.util.LruCache; 6 | 7 | import piratehat.picture.BitmapRequest; 8 | 9 | /** 10 | * Created by PirateHat on 2019/2/21. 11 | */ 12 | 13 | public class MemoryCache implements IBitmapCache { 14 | 15 | private LruCache mLruCache; 16 | 17 | public MemoryCache() { 18 | int maxSize = (int) (Runtime.getRuntime().maxMemory() / 4); //内存的 1/4 作为缓存 19 | mLruCache = new LruCache(maxSize) { 20 | @Override 21 | protected int sizeOf(String key, Bitmap value) { 22 | int size = value.getRowBytes() * value.getHeight();// 返回每一项在内存中大小 23 | return size; 24 | } 25 | }; 26 | } 27 | /* 28 | * 1、getRowBytes:Since API Level 1,用于计算位图每一行所占用的内存字节数。 29 | 2、getByteCount:Since API Level 12,用于计算位图所占用的内存字节数。 30 | 经实测发现:getByteCount() = getRowBytes() * getHeight(),也就是说位图所占用的内存空间数等于位图的每一行所占用的空间数乘以位图的行数。 31 | 因为getByteCount要求的API版本较高,因此对于使用较低版本的开发者,在计算位图所占空间时上面的方法或许有帮助*/ 32 | @Override 33 | public void put(BitmapRequest request, Bitmap bitmap) { 34 | mLruCache.put(request.getMD5CacheKey(), bitmap); 35 | } 36 | 37 | @Override 38 | public Bitmap get(BitmapRequest request) { 39 | return mLruCache.get(request.getMD5CacheKey()); 40 | } 41 | 42 | @Override 43 | public void remove(BitmapRequest request) { 44 | mLruCache.remove(request.getMD5CacheKey()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/config/DisplayConfig.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.config; 2 | 3 | /** 4 | * Created by PirateHat on 2019/2/21. 5 | */ 6 | 7 | public class DisplayConfig { 8 | //加载过程的暂位图 ID 9 | public int PLACE_HOLDRE = -1; 10 | 11 | //错误的显示图 ID 12 | public int ERROR_HOLDER = -1; 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/config/PictureConfig.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.config; 2 | 3 | import piratehat.picture.cache.DoubleCache; 4 | import piratehat.picture.cache.IBitmapCache; 5 | import piratehat.picture.loader.policy.ILoadPolicy; 6 | import piratehat.picture.loader.policy.ReverseLoaderPolicy; 7 | 8 | /** 9 | * Created by PirateHat on 2019/2/21. 10 | */ 11 | 12 | public class PictureConfig { 13 | 14 | private IBitmapCache mBitmapCache = new DoubleCache(); 15 | private ILoadPolicy mLoadPolicy = new ReverseLoaderPolicy(); 16 | private DisplayConfig mDisplayConfig = new DisplayConfig(); 17 | 18 | public IBitmapCache getBitmapCache() { 19 | return mBitmapCache; 20 | } 21 | 22 | public void setBitmapCache(IBitmapCache bitmapCache) { 23 | mBitmapCache = bitmapCache; 24 | } 25 | 26 | public ILoadPolicy getLoadPolicy() { 27 | return mLoadPolicy; 28 | } 29 | 30 | public void setLoadPolicy(ILoadPolicy loadPolicy) { 31 | mLoadPolicy = loadPolicy; 32 | } 33 | 34 | public DisplayConfig getDisplayConfig() { 35 | return mDisplayConfig; 36 | } 37 | 38 | public void setDisplayConfig(DisplayConfig displayConfig) { 39 | mDisplayConfig = displayConfig; 40 | } 41 | 42 | public static class Builder{ 43 | private PictureConfig mConfig; 44 | 45 | public Builder() { 46 | mConfig = new PictureConfig(); 47 | } 48 | public Builder setBitmapCache(IBitmapCache bitmapCache) { 49 | mConfig.mBitmapCache = bitmapCache; 50 | return this; 51 | } 52 | public Builder setLoadPolicy(ILoadPolicy loadPolicy) { 53 | mConfig.mLoadPolicy = loadPolicy; 54 | return this; 55 | } 56 | public Builder setPlaceHolder(int id) { 57 | mConfig.mDisplayConfig.PLACE_HOLDRE = id; 58 | return this; 59 | } 60 | public Builder setError(int id) { 61 | mConfig.mDisplayConfig.ERROR_HOLDER = id; 62 | return this; 63 | } 64 | public PictureConfig build() { 65 | return mConfig; 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/DiskImageLoader.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.net.Uri; 6 | 7 | import java.io.File; 8 | 9 | import piratehat.picture.BitmapDecoder; 10 | import piratehat.picture.BitmapRequest; 11 | import piratehat.picture.ImageViewHelper; 12 | 13 | /** 14 | * 15 | * Created by PirateHat on 2019/2/21. 16 | */ 17 | 18 | public class DiskImageLoader extends BaseLoader { 19 | 20 | @Override 21 | protected Bitmap onLoad(BitmapRequest request) { 22 | final String path= Uri.parse(request.getImageUrl()).getPath(); 23 | File file = new File(path); 24 | if (!file.exists()){ 25 | return null; 26 | } 27 | 28 | BitmapDecoder decoder = new BitmapDecoder() { 29 | @Override 30 | public Bitmap decodeBitmapWithOption(BitmapFactory.Options options) { 31 | return BitmapFactory.decodeFile(path,options); 32 | } 33 | }; 34 | return decoder.decodeBitmap(ImageViewHelper.getImageViewWidth(request.getImageView()), 35 | ImageViewHelper.getImageViewHeight(request.getImageView())); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/ILoader.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader; 2 | 3 | 4 | import piratehat.picture.BitmapRequest; 5 | 6 | /** 7 | * 8 | * Created by PirateHat on 2019/2/21. 9 | */ 10 | 11 | public interface ILoader { 12 | 13 | void loadImage(BitmapRequest request); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/LoaderManager.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | 7 | 8 | /** 9 | * 10 | * Created by PirateHat on 2019/2/21. 11 | */ 12 | public class LoaderManager { 13 | 14 | private Map mStringILoaderMap = new HashMap<>(); 15 | 16 | private static LoaderManager mInstance = new LoaderManager(); 17 | 18 | private LoaderManager() { 19 | register("http", new NetImageLoader()); 20 | register("https", new NetImageLoader()); 21 | register("file", new DiskImageLoader()); 22 | } 23 | 24 | 25 | public static LoaderManager getInstance() { 26 | return mInstance; 27 | } 28 | 29 | private void register(String schema, ILoader loader) { 30 | mStringILoaderMap.put(schema, loader); 31 | } 32 | 33 | /** 34 | * 根据名称获取对应load类型 35 | * @param schema 36 | * @return 37 | */ 38 | public ILoader getLoaderByType(String schema) { 39 | if (mStringILoaderMap.containsKey(schema)) { 40 | return mStringILoaderMap.get(schema); 41 | } 42 | return null; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/policy/ILoadPolicy.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader.policy; 2 | 3 | import piratehat.picture.BitmapRequest; 4 | 5 | /** 6 | * Created by PirateHat on 2019/2/21. 7 | */ 8 | 9 | public interface ILoadPolicy { 10 | 11 | int compareTo(BitmapRequest req1,BitmapRequest req2); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/policy/ReverseLoaderPolicy.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader.policy; 2 | 3 | import piratehat.picture.BitmapRequest; 4 | 5 | /** 6 | * 7 | * Created by PirateHat on 2019/2/21. 8 | */ 9 | 10 | public class ReverseLoaderPolicy implements ILoadPolicy { 11 | 12 | @Override 13 | public int compareTo(BitmapRequest req1, BitmapRequest req2) { 14 | return req2.getSerialNo()-req1.getSerialNo(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/piratehat/picture/loader/policy/SerialLoadPolicy.java: -------------------------------------------------------------------------------- 1 | package piratehat.picture.loader.policy; 2 | 3 | import piratehat.picture.BitmapRequest; 4 | 5 | /** 6 | * Created by PirateHat on 2019/2/21. 7 | */ 8 | 9 | public class SerialLoadPolicy implements ILoadPolicy{ 10 | 11 | @Override 12 | public int compareTo(BitmapRequest req1, BitmapRequest req2) { 13 | return req1.getSerialNo()-req2.getSerialNo(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/btn_arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/btn_arrow_right.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/et_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/et_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ibn_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/ibn_setting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ibn_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/ibn_user.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/imb_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/imb_download.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_10.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_7.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_8.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_game_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_game_9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_10.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_11.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_12.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_13.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_14.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_15.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_7.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_8.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/iv_software_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/iv_software_9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tab_boutique.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/tab_boutique.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tab_category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/tab_category.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tab_collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/tab_collection.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tab_rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/tab_rank.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tab_tencent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/drawable-hdpi/tab_tencent.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/download_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/et_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/navigation_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_green_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_orange_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_red_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_apk.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_boutique.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_category_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_classify.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_collection.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_download_manager.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 14 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 25 | 26 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_rank.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_tencent.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 19 | 20 | 21 | 22 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_apps.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_game.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 17 | 18 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 18 | 19 | 24 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_rank.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_software.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 17 | 18 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_collections.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 23 | 24 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_edit_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 19 | 20 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_apk.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 18 | 19 | 27 | 28 | 33 | 34 | 44 | 45 | 46 | 54 | 55 | 56 | 57 | 58 | 63 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_gridview.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 19 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_main_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_two_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | 16 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 12 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/game.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/main.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/manager.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/software.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-hdpi/software.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3c3f41 4 | #3c3f41 5 | #595b5d 6 | 7 | #e5e5e5 8 | #8b8b8b 9 | #fdfdfe 10 | #f4f4f4 11 | 12 | #000001 13 | #a9a9a9 14 | 15 | #060606 16 | #c9c8c8 17 | #509dfe 18 | 19 | #76e158 20 | #e1ac58 21 | #ff4147 22 | #509dfe 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AppStore 3 | 首页 4 | 游戏 5 | 软件 6 | 管理 7 | 下载 8 | 搜索 9 | 应用信息 10 | 应用进程管理 11 | 下载管理 12 | 安装包清理 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/piratehat/appstore/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package piratehat.appstore; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.0.0' 11 | 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | maven { url 'https://jitpack.io' } 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yishengma/AppStore/b4a86ced1caca96e4b019df8b564c09237dfe493/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Oct 27 11:41:58 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------