| Optimization | Effect |
|---|---|
| Combination of multiple Class files in one DEX file | Smaller memory footprint, faster load of the application |
| Sharing of DEX files between processes (read-only mapping) | Smaller memory footprint, faster load of the application |
| Byte ordering and word alignment according to local machine (install time) | Faster load of the application DEX file itself still platform independent |
| Bytecode pre-verification (as much as possible, install time) | Faster load and execution |
| Install-time optimization of bytecode | Faster execution, still platform independence |
| Register instead of stack based virtual machine | Faster execution (~30%) |
/Users/\<user>/Library/Android/sdk/platform-toolsadb -e shell
adb push \<local> \<remote>
adb pull \<remote> \[\<local>]
adb install \<file>
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<uses-permission/>
<application>
<activity>
<intent-filter>
<action/>
<category/>
<data/>
</intent-filter>
<meta-data/>
</activity>
<service>
<intent-filter>...</intent-filter>
<meta-data/>
</service>
</application>
</manifest>
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
</LinearLayout>
@Composable
fun component() {
Column(modifier = Modifier.fillMaxSize()) {
Text(text = "Hello World!")
Button(onClick = { /*TODO*/ }) {
Text(text = "Button")
}
}
}
A composable function always has the annotation @Composable. Within the function the basic building block is declared
and describes the UI. It might contain several UI elements.
@Composable
fun MovieItem(movie: Movie, onMovieClick: (Movie) -> Unit) {
AsyncImage(model = movie.poster, contentDescription = "poster")
Text(text = movie.title)
Text(text = movie.year)
}
In most of the cases you can just use the standard layout elements like Box, Row or Column to place the items on
the screen.
@Composable
fun MovieItem(movie: Movie, onMovieClick: (Movie) -> Unit) {
Row() {
AsyncImage(model = movie.poster, contentDescription = "poster",)
Text(text = movie.title)
Text(text = movie.year)
}
}
There are also properties to align the elements accordingly:
@Composable
fun MovieItem(movie: Movie, onMovieClick: (Movie) -> Unit) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(model = movie.poster, contentDescription = "poster",)
Text(text = movie.title)
Text(text = movie.year)
}
}
You can also nest elements like you need them:
@Composable
fun MovieItem(movie: Movie, onMovieClick: (Movie) -> Unit) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(model = movie.poster, contentDescription = "poster",)
Column {
Text(text = movie.title)
Text(text = movie.year)
}
}
}
A special property is the Modifier. This can be used to change the size, layout, behaviour of the element. You can
also add information like accessibility labels or test tags. You can also make elements clickable.
Please keep in mind that the order of the modifiers functions is significant because this can affect the final result.
@Composable
fun MovieItem(movie: Movie, onMovieClick: (Movie) -> Unit) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(modifier = Modifier.width(80.dp).padding(8.dp), model = movie.poster, contentDescription = "poster",)
Column {
Text(text = movie.title, fontSize = 20.sp)
Text(text = movie.year)
}
}
}
Scaffold which provides a structure of your screenTopAppBar to display a title and provide navigationText as a label to display textButton to make clickable elementsTextField for text inputsThe MainActivity class is the entry UI component. The onCreate() function belongs to the Activity Lifecycle and is
automatically called by the system. In there you need to call the first composable in the setContent() function:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MovieTrackerTheme {
MovieTracker()
}
}
}
}
To keep in mind that there are still old apps around you need to now the most common types of layouts:
A ConstraintLayout is a android.view.ViewGroup which allows you to position and size widgets in
a flexible way.
A layout that organizes its children into a single horizontal or vertical row. It creates a scrollbar if the length of the window exceeds the length of the screen.
Enables you to specify the location of child objects relative to each other (child A to the left of child B) or to the parent (aligned to the top of the parent).
remember API to store objects in memory. There are 3 different ways to do so:val mutableState = remember { mutableStateOf(default) }var value by remember { mutableStateOf(default) }val (value, setValue) = remember { mutableStateOf(default) }Here is an example:
@Composable
fun helloContent() {
Column(modifier = Modifier.padding(16.dp)) {
var name by remember { mutableStateOf("") }
if (name.isNotEmpty()) {
Text(
text = "Hello, $name!",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
}
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") }
)
}
}
/res/values/strings.xml/res/drawable/res/mipmap/res/layout (not needed with Jetpack Compose)@string) and images
(@drawable):AsyncImage(model = R.drawable.ic_launcher_background, contentDescription = "poster",)
Text(text = stringResource(id = R.string.app_name))
Create a new directory in res/ named in the form <resources_name>-<config_qualifier>
<resources_name> is the directory name of the corresponding default resources<qualifier> is a name that specifies an individual configuration for which these resources
are to be usedSave the respective alternative resources in this new directory. The resource files must be named exactly the same as the default resource files
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
Sizes of view components should be defined in Density Independent Pixels (dp) in order to always get the best results.
More information here.
dp) describes the size of a UI element in a density independent
manner160ppi, one dp corresponds to one physical pixel (px)160ppi, the dp values are converted with the help of the
densityFactordensityFactor describes the device's physical density in relation to the default density of
160ppidensityFactor at runtime:val densityFactor = LocalDensity.current.density
R.java filepublic final class R {
// ...
public static final class layout {
public static final int activity_main = 0x7f030000;
}
public static final class mipmap {
public static final int ic_launcher = 0x7f020000;
public static final int ic_launcher_round = 0x7f020001;
}
public static final class string {
public static final int ButtonText = 0x7f050000;
public static final int app_name = 0x7f050001;
}
}
Note: AndroidX is the successor of the deprecated Android Support Libraries. The usage of the old Android Support Libraries is not recommended anymore for most of the projects.
AppCompatActivity class is the default class used for Activities that want to make
use of the new Material Design features (introduced with API level 21)
build.gradle/build.gradle.kts files