preface

This post has been posted on my Github blog. Welcome to my humble abode:

My Github blog

This article requires existing knowledge:

  • GitGithubBasic use of
  • KotlinGrammar foundation
  • AndroidDevelopment infrastructure

Study list:

  • How to encapsulate your authority framework
  • Publish open source libraries toJitPackThe whole process of the warehouse

Why encapsulate the framework

We often need to apply for run-time permissions in our daily development, so we often write the following string of code


override fun onCreate(savedInstanceState: Bundle?). {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

. // Apply for the CALL_PHONE permission  if (ContextCompat.checkSelfPermission(  this. Manifest.permission.CALL_PHONE  ) != PackageManager.PERMISSION_GRANTED  ) {  ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1)  } else {  call()  } }   override fun onRequestPermissionsResult(  requestCode: Int. permissions: Array<out String>,  grantResults: IntArray ) {  super.onRequestPermissionsResult(requestCode, permissions, grantResults)  when (requestCode) {  1- > { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  call()  } else {  Toast.makeText(this."You denied the permission", Toast.LENGTH_SHORT).show()  }  }  } } Copy the code

Hemp duck, headache, so much code, not only hard to write, but also headache to look at

headache

At this point, it would be nice if the world were simpler and purer

XPermission.request(
    this.    Manifest.permission.CALL_PHONE
) { allGranted, deniedList ->
    if (allGranted) {
 call()  } else {  Toast.makeText(this."You denied $deniedList", Toast.LENGTH_SHORT).show()  } } Copy the code

Does the world feel a lot friendlier? This section of code is much less than before the code does not say, the logic is much clearer duck!

Get to the

Obviously, it uses its own framework, and you’re probably going to be like, “What is this? There are a bunch of permission application frameworks on Github, and they’ve written this neat, beautiful, versatile, and cool thing.”

I want to say: “Yes, you’re right, Github has so many great, fast wheels, but no one else’s dish has its own duck! Xia Zhe teng we can start by encapsulating a simple permission application framework ourselves and learning the whole process of publishing open source libraries to Jitpack/Jcenter. This will spark our interest and make more wheels of our own in the future.

For bosses to the author has good wheels: https://github.com/LoveLifeEveryday/XPermissions

XPermission
Get on the bus

Two. The way into the pit

2.1 createAndroidproject

Create an empty Android project

Create a project

2.2 createGithubproject

To build libraries
  • Then clone the project to a location where the Android project has already been created

  • Copy all the cloned files to the previous directory (note: do not forget to copy the.git file)

  • Delete the cloned XPermission directory

  • Git commit -m “First commit” git push origin master

2.3 implementationXPermission

  1. To the top floorXPermission, create a new onemodule, the choice ofAndroid Library
The new module

Just look at library, as follows

New library successfully created

Then, let’s think about the implementation of runtime permissions. There are three ways:

  • Encapsulate the operations of runtime permissions toBaseActivity
  • Provide a transparentActivityTo deal with
  • Provide a hiddenFragmentTo deal with

In this paper, will be based on the last idea for implementation

2.3.1 createInvisibleFragment


/ * * * created by xucanyou666
 * on 2020/4/23 19:21
* email: 913710642@qq.com * /  typealias PermissionCallback = (Boolean, List<String>) -> Unit  class InvisibleFragment : Fragment() {   private var callback: PermissionCallback? = null   fun requestNow(cb: PermissionCallback.vararg permission: String) {  callback = cb  requestPermissions(permission, 1)  }   / * ** Request a return result * @paramRequestCode Int requestCode * @paramPermissions Array < String > * @paramGrantResults IntArray request result* /  override fun onRequestPermissionsResult(  requestCode: Int. permissions: Array<String>,  grantResults: IntArray  ) {  if (requestCode == 1) {  val deniedList = ArrayList<String>()  for ((index, result) in grantResults.withIndex()) {  if(result ! = PackageManager.PERMISSION_GRANTED) { deniedList.add(permissions[index])  }  }  val allGranted = deniedList.isEmpty()  // Call back the result of the permission request callback? .let { it(allGranted, deniedList) } }  } } Copy the code
  • First of all, let’s define acallbackAs a callback notification of the result of a run-time permission request
  • And then, define onerequestNowmethods
  • The final rewritingonRequestPermissionsResultmethods
The first step

2.3.2 createXPermission

object XPermission {
    private const val TAG = "InvisibleFragment"
    fun request(
 activity: FragmentActivity. vararg permission: String. callback: PermissionCallback  ) {  val fragmentManager = activity.supportFragmentManager  val existedFragment = fragmentManager.findFragmentByTag(TAG)  val fragment = if(existedFragment ! =null) {  existedFragment as InvisibleFragment  } else {  val invisibleFragment = InvisibleFragment()  fragmentManager.beginTransaction().add(invisibleFragment, TAG).commitNow()  invisibleFragment  }  // The asterisk in front of permission means that the array is passed as a variable length parameter  fragment.requestNow(callback, *permission)  } } Copy the code

I believe the code is well understood, so I will not write many comments (actually due to laziness..).

2.4 test

Add library in app\build.gradle

dependencies {
    implementation fileTree(dir: 'libs'.include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx. Appcompat: appcompat: 1.1.0'
    implementation 'androidx. Core: the core - KTX: 1.2.0'
 implementation 'androidx. Constraintlayout: constraintlayout: 1.1.3'  testImplementation 'junit: junit: 4.12'  androidTestImplementation 'androidx. Test. Ext: junit: 1.1.1'  androidTestImplementation 'androidx. Test. Espresso: espresso - core: 3.2.0'  // Add this line  implementation project(':library') } Copy the code

Then apply for any permissions you like

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 makeCallBtn.setOnClickListener {  XPermission.request(this, Manifest.permission.CALL_PHONE) { allGranted, deniedList ->  if (allGranted) {  call()  } else {  Toast.makeText(this."You Denied $deniedList", Toast.LENGTH_SHORT).show()  }  }  }  }   private fun call(a) {  val intent = Intent(Intent.ACTION_CALL)  intent.data = Uri.parse("tel:10086")  startActivity(intent)  } } Copy the code

If you can, congratulations. You’ve made a big step

2.5 release toJitPack

2.5.1 JitPackIntroduction to the

JitPack is a website that allows you to easily publish Git-hosted Java or Android projects (which currently only seem to support Github and the code cloud) to JitPack’s Maven repository. All of its content is accessed over the Content Delivery Network (CDN) using an encrypted HTTPS connection

2.5.2 WhyJitPack

Pros: Easy to pack, saves time, and is backed by Github

Disadvantages: Maven must be added to the root build.gradle file every time the library is imported

Add maven

2.5.3 steps

  • At the root of thebuild.gradleaddmavenThe plug-in

Click to see the latest version

buildscript {
    ext.kotlin_version = '1.3.71'
    repositories {
        google()
        jcenter()
  }  dependencies {  classpath 'com. Android. Tools. Build: gradle: 3.5.3'  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"  // Add the Maven plugin  classpath 'com. Making. Dcendents: android - maven - gradle - plugin: 2.1'  // NOTE: Do not place your application dependencies here; they belong  // in the individual module build.gradle files  } } Copy the code
  • inlibraryThe directorybuild.gradleUnder theapplyPlug-ins and additionsgroup
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
// Add the following two lines
apply plugin: 'com.github.dcendents.android-maven'
// Here LoveLifeEveryday is changed to your Github account name, mine is: LoveLifeEveryday group='com.github.LoveLifeEveryday' android { .} Copy the code
  • synchronized
synchronous
  • Enter it on the command linegradlew installTo build your ownlibraryGo to your local areamavenwarehouse
gradlew install

Wait for BUILD SUCCESSFUL, if BUILD FAIL, it indicates that the BUILD failed, at this time, you should follow the failure prompt to troubleshoot, after completing the error, run gradlew install again, until the BUILD SUCCESS appears

  • Commit the code locallygitwarehouse

Git commit -m “XX”

  • In the localgitWarehouse to playtag
Git tag -a 1.0.0 -m "first version" git push Origin 1.0.0Copy the code
  • Open yourlibarygithubInterface, clickreleaseThat is as follows:
release
  • Click on theDraft a new release, create a new onereleaseThat is as follows:
image-20200424182958983
  • Then fill in the information as follows:
Fill in the information
  • After filling in the information, clickpublich releaseThat is as follows:

  • withGitHubAccount login and registrationjitpack
  • Once logged in, type in your address barlibrarygithubProject address, and then clickLook UpThat is as follows:

  • And then clickGet itIt’s going to roll down, you’re going to roll back up, wait a minute, waitjitpackWhen you finish building there, a green one will appearlog, the construction is successful, as follows:

Then you can happily refer to your open source library in your project as prompted


  • Click on thejitpackCopy the link to yoursReadmeAs follows:
jitpack

2.6 Try using your framework

In app\build.gradle, of course

/ / reference own open-source library implementation 'com. Making. LoveLifeEveryday: XPermissions: 1.0.0'Copy the code

Then try it out

complete

2.7 Beautify your project

A good open source project, readme can’t be worse

Lu Xun said, “Although these jobs won’t make your project awesome, they will make your project beautiful and convenient for others to know about your project.”

For detailed beautification, see this article: How to make your GitHub project look professional

good-looking

Three. I encountered problems in the use

3.1 On the simulatorCallNo response to permission request

  • What happens: InLeisure simulatorOn the testCallpermissions

Why DID I use the Pleasure simulator, that’s another story, right

  • Solution: the real machine test normal application permission, so baidu wave, found that many emulators do notCallThis permission (such as the Night God simulator), I think the original simulator should be able to run normally
  • Conclusion: Simulator of the pot

3.2 uploadJcenterFailed

  • An error occurs at the end of the upload command execution
  • Error:
* What went wrong:
Execution failed for task ':utils:bintrayUpload'.
> org.apache.http.NoHttpResponseException: The target server failed to respond
Copy the code
  • Process:Google && Baidu
  • Conclusion: Network problems
  • Results: tried the ordinary network and Ke Xue Internet, or unable to solve, to useJitPack

If you want to know how to upload to Jcenter, you can check out this article: AS upload Library to Jcenter tutorial + tram log

Bug fading

If the article is a little help to you, I hope you can click on it. Your click on it is my motivation

References:

  • “The first Line of Android code – Version 3”
  • AS upload Library to JCenter tutorial + stomp log
  • How to make your GitHub project look professional
  • Quickly publish open source libraries to jitpack

This article is formatted using MDNICE