How to build your first extension. A complete guide for the newbies

I don’t see a packagename, what do you mean?

1 Like

First of all thank you for this great guide :heart:

The default package name should look like this:
com.appybuilder.Extension_Name
It is something like default package name in kodular for apps.

While if you use extension template or ai sources then you can use custom package name (for example in my case I use com.sunny.Extension_Name).
And this one is same as custom package name in kodular.

4 Likes

Adding to what @vknow360 said, one of the most common usages of package name is to prevent naming conflicts between different classes (for simpler understanding, think of classes to be extensions).
Imagine having two different extensions with the same name, say ‘MyExtension’. Now if you build your project containing both of these extensions, the build process will fail as the compiler won’t be able to resolve the conflicts that have been arisen because of the same name of the classes, or basically extensions. This is where package names help compilers distinguish between different classes having the same name.

Also, package names and the directory structure of your extensions’ source files are very closely related. For example, if your package name is com.company.myExtension (package names are usually written in the reverse domain name notation) then your directory structure must be like this:

src  // This is the main source directory.
└── com
    └── company
        └── myExtension
            └── MyExtension.java
6 Likes

No sooner have 2 days passed than I already have to give up my intention not to post anymore, because this topic is too interesting. Thanks for opening this. (I’m of course also a newbie.)

To create my first extension I used the Extension Template Respository (from Evan Patton).

The first line of my extension (quadraticEquation.java) is:
package de.BodyMindPower.quadraticEquation; // package name of the extension

8 Likes

Thank you all for your replies. So let me see if I understand: in other editors you need to specify the package name in the code, like the example @bodymindpower showed us, but when we use the Appybuilder editor, that package name is generated when we get the aix file. Is that right?

7 Likes

Since you understand and learn very quickly, as we all know, I am sure that you will soon be able to create even these two extensions (definitely sooner than me). :wink:

3 Likes

Next in the template project I see these lines:

import android.content.Context;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.ComponentCategory;

What are each one of these lines?
Where do you get these from? If anyone can explain this in detail, it would be awesome.

That is a VERY long shot :grin: but I hope I would at least be trying something like that soon. I also hope this Q&A will make a lot more people start trying too.

3 Likes

I think here:

3 Likes

They are imports that let you use other packages in your project. Somewhere, there’s a .java file with the package name “com.google.appinventor.components.common.ComponentCategory”, and you’re importing the public methods and fields of that file into yours.
This is where the directory structure @Shreyash was talking about comes in handy. You can expect the file (in this case, ComponentCategory.java) to exist in com/google/appinventor/components/common/
And you would be right in assuming so: appinventor-sources/ComponentCategory.java at master · mit-cml/appinventor-sources · GitHub

If you click on the link, you’ll see there are other .java files in the folder alongside ComponentCategory.java. Suppose you wish to import all of them into your file, you’d use something called a wildcard import. That’s what these lines are:

You’re effectively importing all files inside com/google/appinventor/components/annotations and com/google/appinventor/components/runtime. More on wildcard imports here: Everything You Need to Know about Java Packages and Import Statements

Similarly, these files are present in android/content/Context and android/util/Log. But you won’t find their source code (.java files) in the App Inventor repository. This is because they’re provided by Android and are not specific to App Inventor. (Also note the importance of picking the right package name here. Since the package name in the case above starts with android, we can assume it’s part of Android’s standard library. And the others have com.google.appinventor, which indicates these files are part of App Inventor’s library. (You might wonder why it isn’t com.mit.appinventor, and that’s because these files were originally written by Google. It’s hard to rename packages without breaking compatibility, especially with third-party code, which is why the original package names have probably been retained))

But the source for these Android files surely must exist somewhere… the compiler can’t fetch code from thin air. You’re right, and Java solves this problem by letting us build .jar files. .jars are packaged .java files. They contain executable code (bytecode, if I’m being pedantic) generated from your source code. Google provides one such .jar for the Android library which App Inventor uses in its components. You can find it here: appinventor-sources/android.jar at master · mit-cml/appinventor-sources · GitHub
Further reading on bytecode and libraries if you’re interested:
Java bytecode:
JAR File Overview
Java bytecode - Wikipedia

Some of these imports are essential for your extension to work, while some are optional and depend on what you wish to do with your project. For example, if I were to make a Twitter extension, I’d first look for a .jar supplied by Twitter that contains the endpoints I can use (say, TwitterAPI.sendTweet(…)).
I then download this .jar and add it to my extension. (This is not possible with the online IDEs, by the way. You have to use the extension template or AI repository to include libraries in your project that App Inventor doesn’t already provide). Finally, I import the Twitter packages into my project using the import keyword.

Tip: Avoid wildcard imports as it makes it harder to track where certain parts of your code are coming from. It’s rare that you would want to include all files in a folder. Use it only when needed. java - Using the wildcard when importing packages - Code Review Stack Exchange

12 Likes

And if you’re interested to know why Java uses such a system instead of making all code available everywhere, or placing all functions and variables in a single file/folder, I suggest reading up on Object Oriented Programming and its core principles. Java is an Object Oriented language, and as such sticks to the four fundamental principles laid out here: What are four basic principles of Object Oriented Programming?

9 Likes

Very well explained, thank you @Vishwas! I’ve been reading it many times too understand everything. Now I see why users asked in many occasions if they can import third party libraries.

Is it right to say that all these files are stored somewhere in the online IDE (AppyBuilder or Kodular) and that’s why we can import them but not the third party ones, that’s why we can’t use those?

Also, which ones are “mandatory” or required to use for any type of extension? Example: I just want to make the typical a + b and return the result. Do I need all of these imports shown in the example?

7 Likes

Yes. That is correct.

You will need to import the annotations for every extension. They’re used to expose your Java code as blocks. That’s one required import you’ll find in ALL extensions.
import com.google.appinventor.components.annotations.*;

You’ll also need the ComponentCategory import to tell the system which category to place your extension in.

And it’s generally a good idea to import all files in the runtime folder because your extension will almost always use some functionality already defined in other App Inventor components. (the runtime folder is where you can find the source code for all AI components. If you were making your extension using the AI repository, it’s where you would be placing your extension’s Java file) If you know about “inheritance” in object oriented programming, you’ll see that all extensions “extend” AndroidNonVisibleComponent, which is a file defined in com/google/appinventor/components/runtime.

So, at the least, you’ll need:

9 Likes

@Italo all files are stored into database

3 Likes

Perfect, this is very informative so far.

Very convenient! Long time ago I tried learning how to make extensions but the online IDE’s were not existent yet, so It was a lot more complicated. Is there any difference between the AppyBuilder and the Kodular IDE’s? I know the Kodular one is not available at the moment.
Any plans on unifying them? Any advantages of using one vs the other?

2 Likes

And to take it one step further, is it possible to import third party libraries in the future?

1 Like

I was actually typing a question about that too.
Specifically, what are the steps necessary to do this? :

And I know I’m making a lot of questions, please don’t feel obligated to reply. It can be replied another day or by anyone else. This is going very well by the way.

1 Like

I don’t think so. Both offer pretty much the same functionality. We don’t have any plans to merge them as of now.

We have plans to add this as a paid feature alongside other perks. It’s still a work in progress, though.

To summarise, you have to get the .jar file from the provider, place it in the lib folder of the repository, and add a few lines in the main build.xml file. You should then use the @UsesLibraries() annotation to list the .jar files you’re using in your extension. This is fairly advanced, and I’d recommend looking into this after you’ve got a good idea of how App Inventor components and extensions work behind the scenes.

I’d also suggest glancing over my go-to guide for extensions development. It may be a bit daunting at first, but it does a great job explaining how the App Inventor system works and how you should go about making your own extensions:
https://docs.google.com/document/d/1xk9dMfczvjbbwD-wMsr-ffqkTlE3ga0ocCE1KOb2wvw/pub

6 Likes

Hi @Vishwas

Sometimes I have to use that annotation and sometimes not.It’s quite confusing for me and it increase aix size also.
Can you please tell me when to use that annotation and when not?

1 Like

I am already bad at koding in kodular how would i code an extension :slight_smile:

But its a good choice to make HTML

2 Likes