Service programs, binding directories and activation groups are mainly to do with ILE programs as opposed to OPM programs, so that's probably the best place to start.
In the "good old days" you would write a program in RPG, CL, COBOL, etc and compile it as a single entity which could be called by other programs. For example, you might have an order entry program, ORDR100, which called a separate program, SYSR900, to clear messages from the program message queue.
Each program would exist in its own right and would be called when needed. As you called a program the system would check authorities, etc, and when the initial program ended then so would all the programs further up the call stack. This was the OPM, Open Program Model, and was (for a while) the only way you could do things.
I forget when, but IBM introduced the ILE (Integrated Language Environment) where you would write separate modules in a variety of languages and bind them together to create a program. This way, you could use the best language for the task at hand and mix and match languages within a single program object.
In addition to programs, ILE also allowed you to write service programs which are collections of reusable routines. So, for example, in the order entry program above you might have a service program that consists of various procedures for sending program messages, clearing program message queues, receiving messages, retrieiving message descriptions and so on. A service program is like a DLL in Windows.
When you create your program using the CRTPGM command you can specify, on the command, a list of modules and service programs that you want to bind together to form the program which is fine until the list starts getting longer and you forget to include a module.
This is where binding directories come in. They are just lists of modules and service programs that you want to keep together for creating programs. In my shop I create a binding directory with the same name as the program and define the modules and service programs I need. Then when I compile I use CRTPGM PGM(lib/pgmname) BNDDIR(lib/pgmname) and everything stays together.
Activation groups are slightly more complicated and I think of them as sub-environments. If I have a program that reads FILEA and that calls another program which also reads FILEA then there's the potential that if they are sharing an access path that the file pointer will get moved and the first program won't read the correct records.
With activation groups you can specify that the first program runs in AG1 and the second in AG2, for example, that way each program has its own instance of the file open and there's no conflict. Unfortunately activation groups are a lot more complicated than that and you're probably best off using Google to search for "activation group ILE" or checking out the ILE programmers reference.
Hope it helps