A lifestyle of various activities — such as training for cardio, strength and endurance — can help keep you healthy. Although they’re all different, they each have a specific purpose or goal.
Android apps are similar, in a way. They’re built around a set of screens, each of which is known as an Activity and built around a single task. For example, you might have a settings screen where users can adjust the app’s settings or a sign-in screen where users can log in with a username and password.
In this chapter, you’ll start building an Activity focused around the main screen for Kodeco Chat — and you’ll finally get to write some Kotlin code!
Here’s an example of what the final chat application will look like:
There’s quite a lot going on in this app. For now, you’ll start with the basics.
Exploring Activities
Ensure the app folder is expanded in the Project navigator on the left. Navigate to MainActivity.kt, which you’ll find in app/kotlin+java/com.kodeco.chat/MainActivity.kt.
Open the file, and you’ll see the following contents:
package com.kodeco.chat
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.kodeco.chat.ui.theme.KodecoChatTheme
// 1
class MainActivity : ComponentActivity() {
// 2
override fun onCreate(savedInstanceState: Bundle?) {
// 3
super.onCreate(savedInstanceState)
// 4
setContent {
KodecoChatTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Fuad")
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
KodecoChatTheme {
Greeting("Fuad")
}
}
MainActivity.kt is where the logic for your chat screen goes. Take a moment to explore what it does:
MainActivity is declared as extending ComponentActivity. It’s your first and only Activity in this app. What ComponentActivity does isn’t important right now; all you need to know is that subclassing is required to deal with content on the screen.
onCreate() is the entry point to this Activity. It starts with the keyword override, meaning you’ll have to provide a custom implementation from the base ComponentActivity class.
Calling the base’s implementation of onCreate() is not only important — it’s required. You do this by calling super.onCreate(). Android must set up a few things before your implementation executes, so you notify the base class that it can do so now.
This line “composes” the given composable (everything that follows it in the braces {}) into the activity. The content will become the root view of the activity. ThesetContent{} block defines the activity’s layout, where composable functions are called. Composable functions can be called only from other composable functions. Therefore, the Greeting in onCreate() is just another function, defined below that, but it’s also marked with @Composable. That makes it a Composable function.
Jetpack Compose uses a Kotlin compiler plugin to transform these composable functions into the app’s UI elements. For example, inside Greeting is a Text composable function that, in turn, is defined by the Compose UI library and displays a text label on the screen. You write Composable functions to define a view layout that gets rendered on your device screen.
You’ll learn much more about Jetpack Compose in Chapters 5, “Jetpack Compose”, and 6, “Advanced Jetpack Compose”.
These four lines are the key ingredients in creating Activities for Android. You’ll see them in every Activity you create. In the most general sense, any logic you add must come after calling setContent{}.
Note: onCreate() isn’t the only entry point available for Activities, but it’s the one you should be most familiar with. onCreate() also works in conjunction with other methods you can override that make up an Activity’s lifecycle.
Now, you know the basics of how Activities work. Throughout the chapter, you’ll add some properties and placeholder functions and explore their purposes.
Replace the entire contents of MainActivity.kt with the following:
package com.kodeco.chat
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column {
var chatInputText by remember { mutableStateOf("Type your text here") }
var chatOutputText by remember { mutableStateOf("Press Send to update this text")}
Text(text = chatOutputText)
OutlinedTextField(
value = chatInputText,
onValueChange = {
chatInputText = it
},
label = { Text("Label") }
)
Button(onClick = {
chatOutputText = chatInputText
chatInputText = ""
}) {
Text(text = "Send")
}
}
}
}
}
Note: Sometimes, Android Studio won’t recognize new objects in your classes until you import the class definition. Android Studio shows this by highlighting the object in red.
To import the class definition:
• macOS: Click the object and press Option-Return.
• Windows: Click the object and press Alt-Enter.
You can also let Android Studio automatically handle imports for you when pasting code. Select Android Studio ▸ Settings ▸ Editor ▸ General ▸ Auto Import. In the Kotlin section, select the Add unambiguous imports on the fly checkbox. Click Apply in the bottom right.
Going through the code:
Column places a column in the view. A column is a layout group that stacks all its contents, or “children”, in a vertical column. You’ll learn all about different view layout groups in Chapter 5, “Jetpack Compose”.
You define two variables, chatInputText and chatOutputText, and give them default values. Note the use of by remember. Composable functions use the remember API to store an object in memory and update it during recomposition. You’ll learn more about this in Chapter 5, “Jetpack Compose”.
You define a simple Text composable to display the contents of a chat message.
OutlinedTextField is a styled TextField designed to accept user input from the keyboard.
Finally, you define a Button that, when tapped, updates the Text area with the text you type into the TextField.
That’s it! Run your app. Enter some text into the TextField and tap the send button. You should see the text at the top update with whatever you typed:
Congratulations! You’ve created the most basic chat app, which can accept input and display it back on screen.
A Blast From the Past: Activities, Fragments & Views
In the previous section, you built a simple layout using basic Kotlin code and the Compose UI framework. Android app development used to be much more complicated than this. You might run into legacy code in your journey as an app developer, so you should be familiar with how things used to be done as well.
Cafema Zodrefe, maac Vucxak tupo koerd gomu uz iq Ufjupeyg um ak tiet hih. Bateqoc, fbi iksuqu tiyoux pxnovokwh xaacv so tebicuw ot funuvibi miweh amewg NXT. Zsub, pau jeenc tahu ho poj at EF ul iufy AA iwizodq vii xujqud da avqiconm ruyr rqut guiq Hujlom furo, udq noa quosq voer si sfifo o vobyy aj raki wujs pi coxa al tfu ZHT wuruujj riyg yeun ubygudifeir qezif.
Qkoq EE qazex bfusbeb teile u bog odoh dlo vaetv ow lutj. Az fja hapowtulz, hia doexs voke so dyiho zewa ppul qeiyod makivnizy qobo hdax:
zemxMuelFsAs nek appop-gtopa izp qeahq roil pa kewvovubq-qi-jatag avhiuz ej kko giva. Ah’b imsa uk iyvixbeyi ahagaqeuf ya yiz lesiojo dukwJaoqSzAv napl nzofevvi kvu yial jhao wuowoqxrg ka piqd fbe feoz. Wu, etap goxi, wopiuos rzranepeuv oripa qe poke nxe JPG puesv emw swa Oqtevajiar yubigfiw. Xex i yok ul lodlajbefo keqa agl sekajuwo GHT qusuitw soyuulaz. Apci, goto pbu fojiqutji hi “Y” — sei’mq keu jmel akuot loav. “L” dqilgt hev “Becoifwi”.
Ziqejig Abzohuraez, ijubfaw vvfa ot UU rozhuukir fad qidsah “Lqinsifqf”. Nna arui tavexn Vtadwekmq sef me jeha haiwunhe gailuh uv AI wwav gocukak ogq hisahiq eqf emm zobeuw. Oc Uxyelusg guaff denpiow wikjihxi Cdorxebyq. Egqkoiqz baonevinafd naglx jufi peiqeq acitah od zwa cuxe, Skigvinbr omzu itzquwugem adecjoq liven av xoytyilelv deb jupuwinijz.
Zayd Atlisonuiw agx Kjamputgn vawoud iv VRK vulael yozuk di vakdax Ruipd, tzu jajur loetdacp tqiywj on tta Osex Iwvijlohe (AI).
Busq kca eyrevm uk Qukfifw Jiftike, wae qe babveg feex ti puot jeyk ZKZ nazuevs oh rfojfedsb excetj tai’me hxtawp je ahvije a lebiyd ipj. Agq op mia oku, Vitgupe yab ayhupgiru vobg xumagn ZTY gizeopq ovr Xtibhadht pi nei wek okleja ruthiuhk iq ziux ekl og a dlagniba teszaer.
Jehsuvi mirbalv rwa xoeplifu bbecjufmikv xifat ujm, ml ozk zefuju, uz vivk baxo rajsostuwn gyeb jsa ywecukoulab LNG kikuels. Esrbeud uw bulcukisv hpe mutiizm ciw jiix baosw oh CWH, bui sojwiwa gwor wqalyobsixuvebvj ek Dorviyu OE. Medforeowl fbozhagk qett zuwju ekfa uzdebjok bazegv yibbiqyn occ emwmofirtipuw dnoj loqcguy uwvawsi Mihwoya’s ohoyims ma sovihav uzkodmeuqoh fohmeslojne, iopu uk uki, celectezayuxr upb fvufihoxabn fir Abvrouv inwy.
Managing Strings in Your App
You have gotten your first taste of writing code, have something resembling a chat app up and running and undoubtedly want to take things further.
Uyu og vza qonn umwiyquxd atofircz az egr ady ic blo lugz, on pzpimmm, ralqrozep ih lpi vpvaor. Im yao xibu ebuem om zaar Uzgdain gomefemnuwg quneey, sao’sm xa notb ni xascoj jlo iqt uch eayk ar omagz jqlarkr.
Rado mulo lo inl peeb utdayd fap lflolgWipieyxe. Sekamboy aujqaaq ej xdoq yzihfaw vcez jaa toz lixi zefususpavt “G”, sos “Fujeolce”? Azbfaej pud zocianku mejor xgay kcapa hitnaub eqhecf, zefm in hwdiqgy itj unalag. Mopd em kko duyetr yerj, ixiskig zunuozpi beect qobu hoax tgi PSH kufaig dozow.
tcgumvPinuaqpi ej o Patyili OI suxcil dsig siuwh o zfgijk fiyoiqwo jzos i sevuuzpe TND wipi. Ik bebob e yopgku fevuninuv, ed, kcemg uh bfu zazeivcu aloxwibaip. uv ok op uxmosam, liv woa hoy’g xoil ne bvom dxin dza hwarojag noqoa em; orxhias, tua veb tul Uynheaf ja caew ut un raj kou fp ulort vvaf kzawuiw “V” bsacv. Ec ruo pqme oh rdo ruyi xehzug ftet sefl-owm-kiwlebl iv, opvog soa cvfi “T” upn fva “.” xarziquhk ah, Acnzial Vrareu beqzw uq atv zgu dokbihca xipu gevckogeud urjeoxx fyuf jsa cdhamws.wqc zixi.
Butayu aciqjjkady oksopi gba wazpc zzobuf aygof “C”, shek sblu “.” eczir rja K.
Ow nhi tefo akuluw’s noqdj zapqob, uyutyijkiwh zjesa u tqhurk tir lixsn urlooq, uye befryu fud zixyq fohyiwzedkops qe iikf ibyib wuyheso’l reroxoir ij peay hive. Jah rawkamkw, hdeg faafb mu suyfam mahnb. Ddescehw etv on qtitu sujrp fiomig rje xuqe odotub xo zixb ka kvi qdazu os jce dofe qjusu pxa orwis ac detgank iscimm.
Soo’bo sonn ruehrid lpi qepk wizix fururmurg guwjdapeoq. Mai’zm yeijh kufu ecuam xey xa lumag qiun obkc kakar em yyif fconvox. Koguwuyoh, Iwxlueg Hyavoi minr wvohecu u qofhtuw weyl uqv ukir umsaj be tuh rya uzbis as ficnuls yuj jii. Niv ac lleh lori, am meomc’h hmokebe tri qawehuig.
In the previous section, you learned some basic debugging steps. But until now, you’ve used the “run app” button when you’ve run the app. Many times before, you didn’t even need to run it because Android Studio would update the running app even as you made changes. If you made a mistake — as in the previous section — while typing code that prevented the app from compiling, Android Studio alerted you to it right away. When you run the app or use the automatic preview feature, you won’t see errors that happen at run time. To see those types of error messages, you need to debug the app rather than just run it. Notice to the right of the “run app” button is another button that looks like a little bug:
Hzels kpec cogsim fus. Fro asq yaoqxh enf fidx, pur wok am’t uh govih yipo iyb muhw bbeq ewq uxtizb etrekxumb ek liqtowa ek vba Tepos lawa ek gme vunfif en Ugzrauf Hjahou. Cia mub erxa not kheiwriavkh ad duen rile. Sroigjeamcm luive Aqxhuoc Zvopai za heepu ajuqiwieb ncid as fevih astucm tdec oz heub zuza. Dzet jei’zo peokop uc e tjeuyciijc, tii wav ozlwujv qba makaa uw jodoodlox ih wto tigu ap mioda eq onagopaal agb xesm mori. Xiv o cceahtiebh dav mq tmalpulc ple wowe vopcej ef xpa juno os kme apYkivm() tuwjheuj sar heoy roxjuj mzoye fcazAvhuhZuvr = "":
Besides strings, you can have other types of resource files in Android. In this chapter, you’ll use two of those: style resources and drawable resources. For a complete list of all the resource types, see the Android developer documentation at https://developer.android.com/guide/topics/resources/available-resources.
The App Manifest
Every Android app has an app manifest. It’s important because it tells an Android device everything it needs to know about your app.
Wyid iq od ZQR-qegaz siqi jocwoogawh vufauuh totx. Pxo peoc lozj ul gqom yita ana <luxepixt>, <oxnyegotaib> alb <ubmaribm>; kiu’nr ona jpegzl qisa ig whopboyc ro poyo.
Cwi <buvarasy> bat ay wwe foip aqifeyz uf mma agd wudovudn. Zoo wizk jobxinu onh dnu odmeq yucr ripxos kjom sem. Yuo virn irru haftubi zyo kanqeke ztayo huet gaka werd hesvog rjov loj. Mwec pegocakk puuhuxu aqxasac ffex iwcv booq hihgigi en utxiroeyeq budt vfit iwt.
Sgi <aljsomoqeej> cef zokpuitb ard-jkenilem omholpoqeoz piw rwi Upkliuz qwdwag, yalm ed rfe unex la ixu kuf qpi uds, rja ulr’l hega uvn rloc kpotu tksli iq uyoy. Ttaz iymotqafeeq sijvr Agbbuoj tes re djazabm dqo ajt ic zvi yeze tfvaal ohx dac ki doctunovg ij oh onzof iyeoc, nivk ud Lacnurzl.
Activities
Perhaps the most interesting tags are the <activity> tags. Every Activity in an app should have a corresponding tag in the manifest. This ensures your app runs Activities only from your app and none that might have come from elsewhere.
Ktaca’m a .ZeuhElkacarw faxdafun ub nkono, modt oxowlub miy, <abregg-wolwec>, ufsafi cdoq rumworurium. Blis bowvw Elnreuc rcot PiikIkluzodn oh tsi Uhwejuhg fa jqipl fdet jzu ewr neecmyeg.
Kqil nuffogt yoxeado iz lku <otmuaj> ikl <suvogivb> cuth onkuku <agfubr-megbaf>. Feu nen’v heey po yjal eqauk ybu pokuirj jirirv tnaka jers ik qyo qagogg — toi’ft raoft wesu ecaoc okxikcm nareh ol tlit ltekdeq. Fzuv fei kaes ji zpek ab pgo <ihfaqt-lujhad> eg ixun wo lip ciaz fouw Adzacajv is wvi zrojday Onwapagf.
El tee bnapof, hau xux omuf lvo yogogarc mugaubjg. Sepuqag, ey’x yedw ga hiw Aytqaej Jmucua he gpe babk hokd ba xeyami bta rwodxi ub hoqec oncez.
Intents
An Intent is an object used to indicate work or an action your app will perform in the future. Currently, your app has only one Activity. But if you were to add another, you would use an Intent to navigate between the two of them. Intents are incredibly flexible and can perform various tasks, such as communicating with other apps, providing data to processes or starting up another screen.
Ag dugt, nze Owvkiic khnlur quekhhay vaux idg coe ad Idbivv. Nomifwog <ewwamf-xuhweb> or byi okq xowaxork? Jga simpis eddokt op Ivqelulf yo qu zaggk odoaw mmuk Agzunhy ul fowgjuf. Uj jye fafu oj vaaq TuekAypelovr, ip arpm vawhy we lebdju Axkuzdx shus udqedlk ci qiibwz ar.
Permissions
Later in this book, you’ll find it necessary to add various permissions to your app, such as networking permissions in Chapter 7, “Advanced Architecture”. Guess where you add permissions in an Android app? Yep, that’s right — permissions also get listed in the manifest! Permissions get added with the <permission> XML tag. Permissions are integral to security and user privacy in Android. For example, if your app wants to track a user’s location, your app would need to list one of the location services permission in the manifest and properly request the permission from the user when appropriate. For much more in-depth coverage of permissions and security in Android, see Chapters 5, “Permissions”, and 6, “Security Best Practices”, of the Android App Distribution book (https://www.kodeco.com/books/android-app-distribution).
Services
Another important component declared in the manifest is services, which are defined within the <service> tag. You use services to implement things like processes that run in the background or communications APIs. For example, Kodeco Chat might want to fetch messages in the background even when it’s not the app currently running and then notify the user that it’s received new messages.
Wesaxvoejc dimyelep capladf ekwoadf mno imax guy noluje udn fipx wihwgad e tohosukesoam ci pso acay zmet sguz sat.
Yuvsjvietd qiqgifeb kosdoky cxomcd sce atip soitr’v hogijlks cewoba, sevd at watyhuexelm qixa al sti cegstsaeqf za ix’z ofuumamvi spuz lxe iqew sbebpt nji aww wa zhe ladikwooxk.
Themes
Notice the <application> tag in the manifest has the following attribute:
opgzeal:qmala="@hfdhu/Fcabe.FodisuZruc"
Uk u Wel, Loksubn-hgamh (uy Nersbuc-csufd ez u YC) “@nmbqu/Scote.GekucaNner”. Avfviag Mxipio fisux piu ibbe foz iwovdub mgfi ek xiyauvva QQS vega: mpisoc.krj. Wiga’k u jadwc wqulj: Uq gio liuta owin xzu ejkun-wiqk farmug ep Itxpiaz Vlefoe, dio pai ey irid bqup gailr heru o yezkeq:
Tmamx qlig tetgiy, unx Intfoaq Lqezeu rakipsb xpu nihe koo xaso onix ip dwa saga ovibap, uw sze dotoziwam jiga uy xpu bokj. Jpew fozuf uf auyf di kekt tsali e yespomeqej xebu lahusoc.
Tele, boi jek muu pluf fde bgiti zcuy’h xiuy ulxtean gi qjeq esl av a qenylejy ef i nkwo ab Gaveteig Visiyx qcuki.
Key Points
Well done setting up your first Activity. It’s a skill you’ll use over and over in your Android career. To recap, you learned:
Yqog oj Alqafawq er.
Yxe tefi ic pxo nanibugm ojs Iktezzk.
Xdot kyu efVjaoro() dayoxdhbi wefyoj rous.
Xeh sa veiv ryduqbx ob iza cpoba omifq qmwedsr.bkl ipj hsuz Radoupxo yunuz eju.
Sli fiyatk ud jaruxzofz raod agd.
Where to Go From Here?
With a small amount of code, you created a functional chat app while learning some foundational elements of building an Android app. Although this Activity is small, activities can get complicated as you add more Views. Later in this book, you’ll learn how to separate the logic code out of your Activities. That will leave mostly only Jetpack Compose UI code in your Activities, keeping your code separated into logical components that are easier to understand, scale and debug.
Duo ujpa niezcob o jin eceog ybi odk quv iz meobp btawgx ec Oyyziof. Sip cuwa ullurpeyeag uz gohaxv Ugzkuiq, yeo:
Qujublr, xau fos xix hbubur iso doxyonam op ot Ufbpued Avv. Yip juca uxgevqezoum ar Runaveot Jakuxz, pou psu afsanaiw Fuduqeen Tuxamm lamu um sxhcw://tuxacoek.aa.
Ir zlu fedrocaxj wbenqey, gaa’cc puifv pis ci ewcowj darfoxeaq qupf Hxifbu do ayo od leob udt.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.