0

how to make android 2.2 app work in android 4 ? Is it a great refactoring work? or is it just some sdk settings to change in the project?

BTW : which the better case : - adapted android 2.2 app that will work with android 4 ? - android 4 app with compatibility package from google ?

Thanks in advance?

EDIT: I ask this because my app runs fine in android 2.2 and 2.3 but crashes in android 4.

StackTrace :

E/AndroidRuntime(  660): FATAL EXCEPTION: main
E/AndroidRuntime(  660): java.lang.RuntimeException: Unable to start activity ComponentInfo{vex.android/vex.android.controllers.ControllerLoginView}: java.lang.NullPointerException
E/AndroidRuntime(  660):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
E/AndroidRuntime(  660):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
E/AndroidRuntime(  660):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
E/AndroidRuntime(  660):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
E/AndroidRuntime(  660):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  660):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(  660):    at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime(  660):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  660):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(  660):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime(  660):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime(  660):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(  660): Caused by: java.lang.NullPointerException
E/AndroidRuntime(  660):    at vex.android.layout.layout_titleheader.setButtonVisibility(layout_titleheader.java:163)
E/AndroidRuntime(  660):    at vex.android.layout.layout_titleheader.setButtonVisibility(layout_titleheader.java:155)
E/AndroidRuntime(  660):    at vex.android.controllers.ControllerLoginView.Initialize(ControllerLoginView.java:58)
E/AndroidRuntime(  660):    at vex.android.definition.VexActivity.onStart(VexActivity.java:154)
E/AndroidRuntime(  660):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1133)
E/AndroidRuntime(  660):    at android.app.Activity.performStart(Activity.java:4475) 
E/AndroidRuntime(  660):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929)
E/AndroidRuntime(  660):    ... 11 more

layout_titleheader.java :

    package vex.android.layout;

    import vex.android.R;
    import vex.android.controllers.ControllerInfo;
    import vex.android.definition.VexLayout;
    import vex.android.definition.iVexParentable;
    import vex.android.definition.intentCode;
    import android.app.Activity;
    import android.app.Instrumentation;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.SystemClock;
    import android.util.AttributeSet;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageButton;
    import android.widget.ImageView;


    public class layout_titleheader extends VexLayout
    {
        /*** CONTROL POINTERS ***/
        Button nextButton;
        Button prevButton;
        ImageView infoButton;
        ImageButton upButton;
        ImageButton downButton;

        private Handler handler = new Handler(); 
        private Runnable upTask = new Runnable() { 
            public void run() {
                if(getContext() instanceof iVexParentable) {
                    ((iVexParentable)getContext()).onUpButton();
                }
                handler.postAtTime(this, SystemClock.uptimeMillis() +  100); 
            } 
        };
        private Runnable downTask = new Runnable() { 
            public void run() {
                if(getContext() instanceof iVexParentable) {
                    ((iVexParentable)getContext()).onDownButton();
                }
                handler.postAtTime(this, SystemClock.uptimeMillis() +  100); 
            } 
        };

        /**** CONSTRUCTORS ****/
        public layout_titleheader(Context context)
        {
            super(context);
            ((Activity)getContext()).getLayoutInflater().inflate(R.layout.layout_titleheader, this);
        }
        public layout_titleheader(Context context, AttributeSet attrs) {
            super(context, attrs);
            ((Activity)getContext()).getLayoutInflater().inflate(R.layout.layout_titleheader, this);
        }

        /**** INITIALIZERS ****/
        @Override
        public void Initialize()
        {
            infoButton.setOnTouchListener(new OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction() == MotionEvent.ACTION_DOWN) 
                    {
                        showInfo();
                    }
                    return true;
                }
            });

            prevButton.setOnTouchListener(new OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction() == MotionEvent.ACTION_DOWN)
                    {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                Instrumentation i = new Instrumentation();
                                i.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
                            }
                        }).start();
                    }
                    return true;
                }
            });

            nextButton.setOnTouchListener(new OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction() == MotionEvent.ACTION_DOWN)
                    {
                        if(getContext() instanceof iVexParentable)
                        {
                            ((iVexParentable)getContext()).onEditButton();
                        }
                    }
                    return true;
                }
            });
            upButton.setOnTouchListener(new OnTouchListener() {
                public boolean onTouch(View view, MotionEvent motionevent) {
                    int action = motionevent.getAction();
                    if (action == MotionEvent.ACTION_DOWN) {
                        handler.removeCallbacks(upTask);
                        handler.postAtTime(upTask, SystemClock.uptimeMillis() + 100);
                    } else if (action == MotionEvent.ACTION_UP) {
                        handler.removeCallbacks(upTask);
                    }
                    return false;
                }
            });

            downButton.setOnTouchListener(new OnTouchListener(){
                @Override
                public boolean onTouch(View v, MotionEvent motionevent) {
                    int action = motionevent.getAction();
                    if (action == MotionEvent.ACTION_DOWN) {
                        handler.removeCallbacks(downTask);
                        handler.postAtTime(downTask, SystemClock.uptimeMillis() + 100);
                    } else if (action == MotionEvent.ACTION_UP) {
                        handler.removeCallbacks(downTask);
                    }
                    return false;
                }
            });
        }

        @Override
        public void InitializeControls()
        {
            infoButton = (ImageView)findViewById(R.id.infoButton);
            prevButton = (Button)findViewById(R.id.prevButton);
            nextButton = (Button)findViewById(R.id.nextButton);
            upButton = (ImageButton)findViewById(R.id.upButton);
            downButton = (ImageButton)findViewById(R.id.downButton);
        }

        /**** LOCAL METHODS ****/
        public void showInfo()
        {
            if(getContext() instanceof Activity)
            {
                Intent intent = new Intent(getContext(), ControllerInfo.class);
                ((Activity)getContext()).startActivityForResult(intent, intentCode.INFO_DOSTART);
            }
        }
        public void setButtonVisibility( int previousButton, int editButton, int helpButton)
        {
            setButtonVisibility(previousButton, editButton, helpButton, View.INVISIBLE, View.INVISIBLE);
        }

        public void setButtonVisibility( int previousButton, int editButton, int helpButton, int upButtonVisibility, int downButtonVisibility)
        {
            if (View.VISIBLE == previousButton) {// fixes issue of translation not correctly displayed
                prevButton.setText(getContext().getString(R.string.Back));
            }
            prevButton.setVisibility(previousButton);
            nextButton.setVisibility(editButton);
            infoButton.setVisibility(helpButton);
            upButton.setVisibility(upButtonVisibility);
            downButton.setVisibility(downButtonVisibility);
        }

        public void setPreviousButtonText(int id) {
            prevButton.setText(getContext().getString(id));
        }

        public void setEditButtonName(int resId)
        {
            nextButton.setText(resId);
        }
    }

After some digging, I found that onFinishInflate() from View class that is overriden in VexLayout is NOT called when running android 4. Any idea?

Alexis
  • 16,629
  • 17
  • 62
  • 107

3 Answers3

1

Android platform is generally forward-compatible. It means that you can write your app for SDK 8 (2.2) and it will run on 4.0.

UPDATE: Try to check whether one of Views(for example prevButton or nextButton) equals null, getContext or Context.getString(int)returns null in method setButtonVisibility(int, int, int, int, int)

pepyakin
  • 2,217
  • 19
  • 31
  • Indeed on android 4 nextButton is null at the time setButtonVisibility is called but not in android 2.2. How can it be possible? – Alexis Apr 10 '12 at 07:02
  • Hm. Can you send to me your app project with sources? – pepyakin Apr 10 '12 at 15:01
  • finally I debugged it but that's still weird : http://stackoverflow.com/questions/10088751/why-onfinishinflate-isnt-called-on-my-android-views-in-android-4 – Alexis Apr 10 '12 at 15:24
0

Android has backward compatibility, so an app written for android 2.2 should work on android 4.

Mark268
  • 78
  • 1
  • 8
0

It is possible. I think if you try to install it in android 4, it will install normally. But if you try vice versa, then it is not possible. Because there are many advance changes that android 4 provides.

Sanchit Paurush
  • 6,114
  • 17
  • 68
  • 107