As you know, there are two ways to work with git in Android Studio.
The first classic way is to use the console. The advantage of this approach is, first of all, reliability. The GUI can hang and, for example, hang at the rebase stage so that abort / continue / switching to another branch will not help. Console commands will help you, they are always trouble-free.
The second way is to use the GUI provided by Android Studio. The advantages are obvious - a lower entry threshold, it is more clear what can be done at all. And also there are various buns from the studio itself for the convenience of working with git. One of them will be discussed. By the way, using the GUI, you can also leave the mouse alone and use hotkey
Hotkeys used in the article
Shift + Shift (double-click shift) - Search window. Allows you to search for both code / resources and various actions and settings.
Ctrl + Alt + L (⌘ + ⌥ + L) -> Code Formatting
Shift + Ctrl + Alt + L (⇧ + ⌘ + ⌥ + L) → Code Formatting → Code Formatting with Parameters.
What is it all about and where to find it?
, , — , , pull request. , hotkey Ctrl+Alt+L, .
Idea/AndroidStudio ,
commit' Android Studio :
, , Before Commit. ,
?
✓ Reformat code
code style. ctrl+shift+alt+L clean up.
code style Settings → Editor → Code Style
Applies line indentation in accordance with the code style (For details, see Code Style, in the section of the same name)
In the example, the spaces used to form indentation (marked with dots) will be replaced by tabs (marked with an arrow)
Before commit
class CleanTab(context: Context) {
....val date = Date()
....val button = Button(context)
....val textView = TextView(context)
....val ratingBar = RatingBar(context)
....val imageView = ImageView(context)
}
After commit
class CleanTab(context: Context) {
-> val date = Date()
-> val button = Button(context)
-> val textView = TextView(context)
-> val ratingBar = RatingBar(context)
-> val imageView = ImageView(context)
}
code-style.
Date, button =, args main {
class CleanSpaces(context:Context) {
val date = Date( )
val button= Button(context)
fun main(arg: Args){
}
}
class CleanSpaces(context: Context) {
val date = Date()
val button = Button(context)
fun main(arg: Args) {
}
}
. , / .
else, catch , ( code style)
manyArguments 80 ( code style),
class CleanWrappingAndBraces {
fun condition() {
if (liveData != null) {
<..>
}
else {
<..>
}
}
fun catching() {
try {
<..>
}
catch (e: Exception) {
<..>
}
}
fun manyArguments(userId: Int, issuerCountryId: String, sendingCountryId: String, receivingCountryId: String) {
}
}
class CleanWrappingAndBraces {
fun condition() {
if (liveData != null) {
<..>
} else {
<..>
}
}
fun catching() {
try {
<..>
} catch (e: Exception) {
<..>
}
}
fun manyArguments(userId: Int, issuerCountryId: String,
sendingCountryId: String,
receivingCountryId: String) {
}
. ( Code Style, )
}, 2
class CleanBlank {
fun foo() {
}
fun bar() {
}
}
class CleanBlank {
fun foo() {
}
fun bar() {
}
}
Rearrange code
, -. XML HTML . Setting → Editor → CodeStyle → XML/HTML → Arrangement
! . Rearrange , , . : LinearLayout, , Button TextView, . —
xmlns , code-style(xmlns:android , xmlns:<...> .
, xmlns:tools xmlns:app , . , rearrange
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools" android:layout_height="match_parent"
android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto">
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
android:padding code-style. style android:id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:srcCompat="@tools:sample/avatars" />
<TextView
style="@style/TextAppearance.MaterialComponents.Body1"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/title"
style="@style/TextAppearance.MaterialComponents.Body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World" />
</LinearLayout>
Optimize import
, code style. ctrl+shift+alt+L optimize import.
optimize imports import java.util.* , ,
import android.content.Context
import android.widget.Button
import java.util.*
class RemoveUnused(context: Context) {
val button = Button(context)
}
import android.content.Context
import android.widget.Button
class RemoveUnused(context: Context) {
val button = Button(context)
}
n , .
m enum java static ,
Settings → Editor → Code Style → Kotlin → Imports
android.widget android.widget.*
import android.content.Context
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.RatingBar
import java.util.*
class MergeImport(context: Context) {
<..>
}
import android.content.Context
import android.widget.*
import java.util.*
class MergeImport(context: Context) {
<..>
}
, (m = 0, n=0), ( ) // .
import android.widget. import java.util.
import android.content.Context
import android.widget.*
import java.util.*
class MergeImport(context: Context) {
<..>
import android.content.Context
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.RatingBar
import java.util.*
class MergeImport(context: Context) {
<..>
}
, ,
import android.content.Context
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.util.*
import android.widget.RatingBar
class SortImport(context: Context) {
<..>
}
import android.content.Context
import android.widget.Button
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import java.util.*
class SortImport(context: Context) {
<..>
}
Perform code analysis
. . — , , , Deprecated
fun TextView.format(message: String) {
val htmlText = Html.fromHtml(message)
}
, :
Review :
Check TODO
, TODO, . , //TODO, //FIXME, todo, Setting → Editor → TODO.
todo, .
Clean up
. (. ), deprecated . Actions → Code cleanup. , .
:
- deprecated ( )
- view
! , !
-, .. non-nullable
data class User(val firstName: String, val secondName: String)
val user = User("", "")
fun getUserFullName(): String {
val firstName = user?.firstName
val secondName = user.secondName ?: return firstName
return "$firstName $secondName"
}
data class User(val firstName: String, val secondName: String)
val user = User("", "")
fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
public, ..
data class User(val firstName: String, val secondName: String)
val user = User("", "")
public fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
data class User(val firstName: String, val secondName: String)
val user = User("", "")
fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass() {
doIt()
}
class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass {
doIt()
}
deprecated ReplaceWith(), cleanup . , — , ReplaceWith(). . / . / , ( ), , , . ,
@Deprecated(" ", ReplaceWith("newMethod()"))
fun oldMethod() = Unit
fun newMethod() = Unit
@Deprecated(" ", ReplaceWith("NewClass"))
class OldClass
class NewClass
class GetDeprecatedCodeUseCase(val clazz: OldClass) {
init {
val initData = oldMethod()
}
}
@Deprecated(" ", ReplaceWith("newMethod()"))
fun oldMethod() = Unit
fun newMethod() = Unit
@Deprecated(" ", ReplaceWith("NewClass"))
class OldClass
class NewClass
class GetDeprecatedCodeUseCase(val clazz: NewClass) {
init {
val initData = newMethod()
}
}
, Android Studio . , , , . , .
:
Optimize import Reformat code . .
Rearrange Clean up . , - , (Rearrange) (Clean up)
Check TODO and Perform code analysis can also be used fearlessly. They do not affect the code in any way, they only give annoying hints. Yes, if everything in your project is completely built on TODO and Deprecated code, then there will be no end to them, and they will be more annoying. But if you have a fairly clean code in your project and you try to minimize such moments, then the helpers will give an excellent chance to revise the code where you could have made an omission.