I'm familiar with Java but am just starting out Android programming, and don't really know what I need to make things happen. I'm trying to work with a Canvas, I'm basically making an app that reads real-time data and makes a constantly changing graph based off of it, with some buttons and other interactive UI. What are the methods I need to implement? For example, in "regular" Java, I know I would NEED to have
public void init(){//...}
public void paint(Graphics g) {//...}
public void run(){//...}
public static void main (String argv[]) {//...}
//...and more
Based on sample code that I found it seems like I need the following general outline (plus my own miscellaneous functions and classes).
public class MyClass extends Activity{
public void onCreate(Bundle savedInstanceState){//initialization and setup}
public class MySurfaceView extends SurfaceView implements Runnable{
public MySurfaceView(Context context){//constructor}
public void onResumeMySurfaceView(){//???}
public void onPauseMySurfaceView(){//deal with user leaving the activity}
public void run(){//...}
public boolean onTouchEvent(){//...}
}
}
Do I need all of these? What more/else do I need? And, what goes in each of the methods (e.g., where does the stuff I would normally put in paint(Graphics g) go)?
I realize this is a very general question that's kind of big, and would appreciate either tips or a link to a tutorial that is more specific than, say, http://developer.android.com/reference/android/app/Activity.html
http://www.amazon.com/Hello-Android-Introducing-Development-Programmers/dp/1934356565/ref=sr_1_1?ie=UTF8&qid=1309211182&sr=8-1
I would suggest getting a good book like the one above.
Related
I am looking for an example of an interface with a listener, so any class implementing the interface also needs to have the listener. For the interface below I wanted to have a listener to callback when the ImageView is loaded. One class will use a bitmap, the other will use a uri. In either case
My interface
public interface ITokenMessageService {
public void sendAcknowledgement();
public void sendReceived();
public void sendFinished();
public void displayToken(ImageView imageView, [here is where I want the callback]);
}
This may seem rather simple but the queries for interface returned a lot of UX responses and because you implement an interface for a listener, there were a lot of responses for that as well, so I was having trouble finding an example.
public interface ITokenMessageService {
public void sendAcknowledgement();
public void sendReceived();
public void sendFinished();
public void displayToken(ImageView imageView, YourCallback callback );
//You could have a get function in your interface
//thus anything implementing it, needs to have a function that returns
//the callback, ie it has it.
public YourCallback getYourCallback();
}
In reality this doesn't make much sense though, as why would you need to guarantee the implementer also has the callback through an Interface? If its using the displayToken function it HAS to have it or have access to it anyways, its a moot point.
I have the following (simplified) rig so far:
MyActivity.java:
public class MyActivity extends Activity {
public GLSurfaceView myGLView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myGLView = new MyGLSurfaceView(this);
setContentView(myGLView);
}
}
MyGLSurfaceView.java:
public class MyGLSurfaceView extends GLSurfaceView {
private MyRenderer mMyRenderer = new MyRenderer();
private MyThread mMyThread = new MyThread();
public MyView(Context context) {
super(context);
setRenderer(mGameRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
mGameThread.setRunning(true);
}
}
MyRenderer.java:
public class GameRenderer implements GLSurfaceView.Renderer {
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// ...
}
}
MyThread.java:
Here I'm doing all initializations, creating objects and so on.
public class MyThread extends Thread {
private MyObject mMyObject = new MyObject();
public MyThread {
// ...
mMyObject.setRot();
this.start();
}
public void run() {
// Fixed Timestep Loop goes here
mMyObject.getRot();
}
}
MyObject.java:
This is a sample object which holds different fileds and methods.
public class MyObject {
private double mRot;
// Getters & Setters
protected double getRot() { return mRot; }
protected void setRot() {
// ... Do calculations
}
public void draw() {
// OGL Instructions go here
gl.glRotatef(1.2f, 0, 0, setRot());
}
}
Now the problem I was running into is the following: (I guess, I missed something very basic and simple :) )
As stated above, I'm creating my object instances in the MyThread class. The Thread is created in the MyGLSurface class, same goes for the Renderer. Now, that I have that two threads I can't figure out, how to use that one instance and their methods in that two separate threads.
I tried different approaches, but nothing did work. So in my opinion I made a mistake in the class design. I mean, I don't just want to get it running (that'd be quite easy), but I want to know how to do it correctly.
The main problem is actually that I can't access the MyObject's instance and simply use the draw() method in the renderer - because I don't get it.
I thought, it would be possible to call the draw() method of MyObject within the rendering thread without the need of using a singleton and so on. So simply referencing the instance to it. But somehow that seemed weird and dirty (besides that it doesn't work for me).
I tried dozens of different approaches, but I really need a bump into the right direction. I'm quite familar with OOP, but here I might really miss something.
In that many samples I found on the web (stackoverflow, Replica Island, different tutorial sites, Google I/O, DevCentral, etc.) they either didn't use a multithreaded system or they split it directly (GL objects from regular objects).
Any hint into the right direction would be much appreciated!
Another example to peruse:
https://code.google.com/p/android-breakout/
The wiki and code comments discuss the threading issues inherent in using GLSurfaceView. In particular, the game does as much setup as it can before the Renderer thread starts; once it's running, as much work as possible is done on that thread. The game state objects are effectively "owned" by the renderer thread, and the Activity is owned by the UI thread, so any "off-thread" interactions are handled by sending messages rather than making direct method calls. For example, see the handling of touch events.
It's good that you're thinking about this -- you either need synchronization or careful object discipline to avoid nasty race conditions.
See also: android game loop vs updating in the rendering thread
The nice thing about GLSurfaceView is that it creates the OpenGL rendering thread for you, so you don't need to create one yourself. The main UI thread will call the OnDraw() method in your view class and that's all the threads you need. If you really want to create your own thread for OpenGL rendering, use TextureView instead of GLSurfaceView. Here is an article that I think will help:
http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1
I know a good amount of java but this is my first time programming with the android sdk. I need to get the rotation of the phone in real time and display it on the screen. I was wondering what sensor method to use, as I heard that getOrientation was processor intensive and may not work in real time. Secondly, I was wondering which class I'd right this program in, I don't quite understand android class hierarchy yet. Thirdly, how would I make the numbers change on the screen in real time?
Thanks for the help!
I was wondering what sensor method to use, as I heard that getOrientation was processor intensive and may not work in real time.
You'll want to have a look at the OrientationEventListener object.
Secondly, I was wondering which class I'd right this program in, I don't quite understand android class hierarchy yet.
To get you started, you could build all this code into an Activity. Unlike a traditional Java program there is no main() entry point method and you won't user the constructors of application component classes to instantiate them. Lifecycle callback methods like onCreate() and onDestroy() are where you will want to do initialization and teardown of instance information. This guide may help you in how to construct your application to use a single Activity.
Thirdly, how would I make the numbers change on the screen in real time? Thanks for the help!
The OrientationEventListener includes a callback method for each change, simply use this callback to update a view in your UI.
Here is a simple example pulling it all together:
public class OrientationActivity extends Activity {
private OrientationEventListener mListener;
private TextView mTextView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
setContentView(mTextView);
mListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_UI) {
#Override
public void onOrientationChanged(int orientation) {
mTextView.setText(String.valueOf(orientation);
}
};
}
#Override
public void onResume() {
super.onResume();
mListener.enable();
}
#Override
public void onPause() {
super.onPause();
mListener.disable();
}
}
I have a real problem using my app that involve 2 processes. One process its executing a Service (p1) and the other the GUI (p2).
I have a class in p2 that implements the use of an object (iThing) that is custom memory managed (and its static). It has to be like this bacause of Android OS implementation of destroying the views whenever he wants.
public class Connections{
public static int iGlobalCounter=0;
public static Object iThing;
public static void start(){
iGlobalCounter++;
Log.d("PROCESS", "UP: "+iGlobalCounter);
if (iGlobalCounter<=1){
//Create the object "iThing"
}
}
public static int stop(){
iGlobalCounter--;
Log.d("PROCESS", "DOWN: "+iGlobalCounter);
if (iGlobalCounter<=0){
//Destroy the object "iThing"
}
}
}
The main GUI (in p2), starts and stops the variable on the onCreate / onDestroy (for all views in my app)
public class MyMainClass extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Connections.start();
}
#Override
public void onDestroy(){
super.onDestroy();
Connections.stop();
}
}
Finally in p1 I have the service, which also needs the variable, so, it does the same
public class MyMainService extends Service{
#Override
public void onCreate() {
super.onCreate();
Connections.start();
}
#Override
public void onDestroy(){
super.onDestroy();
Connections.stop();
}
}
The problem is that if I use only p2 (GUI), it goes all well, but when I execute the service (in p1), the counter doesn't increment from the last state, but from 0, resulting in destroying the object when leaving the service, not the app.
if do this navigation, I get the following counters:
MyMainClass (1) --> OtherClass (2) --> AnotherClass (3) --> MyMainService (1)
My question is if there is a way of having a multi-process global variable? As it seems that every process takes its own static variables and are not "real static". A solution could be using SharedPreferences to save the state, but not really nice solution, as it hasn't to be saved when leaving the app.
Thanks,
PAU
I think that you should extend Application class and put your globalVariable there.
You can store your global data in shared memory (see MemoryFile).
To synchronize access to the file, I think the best approach is to implement some sort of spinlock using the same memory file.
In and case, I don't know a simply way of doing this.
You have the following options which you can look into for sharing data between different processes,
Message Queue,
Named Pipes,
Memory mapped files
WCF on Named Pipes or MSMQ
That's probably part one of my question.
Basically I'm struggling with the actual injection for version 1.1.2. I've read the couple of pages on the site, and I feel I'm missing something.
Basically I've done the RoboApplication extension. I've overridden the addApplicationModules method. I've even made a module.
My module looks like this:
public class DataRepository extends AbstractAndroidModule
{
#Override
protected void configure() {
/*
* This tells Guice that whenever it sees a dependency on a TransactionLog,
* it should satisfy the dependency using a DatabaseTransactionLog.
*/
bind(IDataBaseAdapter.class).to(DataBaseAdapter.class);
}
}
In my adapter I have this:
public class DataBaseAdapter implements IDataBaseAdapter
{
private DataBaseHelper _dbHelper;
private SQLiteDatabase _db;
#Inject
protected static Provider<Context> contextProvider;
public DataBaseAdapter()
{
_dbHelper = new DataBaseHelper(contextProvider.get());
}
}
If I don't do there, where is the opportune place for the chunk of code to reside... where I associate injectors?
Finally... my Application has an injection of it like so:
public class MyApplication extends RoboApplication
{
public MyApplication()
{
super();
}
public MyApplication(Context context)
{
super();
attachBaseContext(context);
}
#Override
protected void addApplicationModules(List<Module> modules)
{
modules.add(new DataRepository());
}
#Inject
private IDataBaseAdapter adapter;
public IDataBaseAdapter getAdapter()
{
return adapter;
}
public void setAdapter(IDataBaseAdapter value)
{
adapter = value;
}
...
}
I'm trying to use the Inject attribute as shown. For example:
#Inject
private IDataProvider provider;
A couple of reasons why I'm lost is that I come from a .NET and Flash/ActionScript background plus I've only used StructureMap instead of Ninject (in the .NET world), which I've heard Guice is designed with some of the ideas of Ninject in mind. Could someone help me figure out this small piece?
I'd really like to focus on using 1.1.2 instead of jumping to 2.x of RoboGuice... especially since it is still in beta, so I hope you all don't mind.
Thanks again,
Kelly
Android is quite different from standalone / hosted java application. You do not have main() , but you have certain activity units, which are managed by android framework (activities, services , broadcast receivers)
DI is a technique which allows you to eliminate booler plate code by wiring together
parts in good object oriented way.
As your unit of work is mostly activity, you shall do wiring / creation of your collaborating objects in onCreate() method , and there are dedicated onResume() and onPause() methods (see actviity lifecycle)
Rule of thumb is, does this thing needs to be restarted every time activity loses it focus? If yes, initialize / destroy it in inResume() / onPause(), otherwise - in onCreate()
And if you like to share objects withing entire application ( running in same JVM ) , it is OK to use singleton pattern in android. So you may just have singleton injector factory , and cosult it from everywhere:
InjectorFactory.getInstance(<context if necessary?>).getInstance(whatever you need);
OK, I've figured out what was needed, but I'm not quite sure why after seeing all the information floating out there.
I basically made this change, and now my test passes.
public class DataBaseAdapter implements IDataBaseAdapter
{
private DataBaseHelper _dbHelper;
private SQLiteDatabase _db;
#Inject
public DataBaseAdapter(Provider<Context> contextProvider)
{
_dbHelper = new DataBaseHelper(contextProvider.get());
}
}
While I like using constructors as the tool for injecting, I wonder why it had to work this way, considering that examples I have seen are some kind of reflection class injection.
Anyway, that's this part. Hopefully someone else will find this useful.
Cheers,
Kelly