Best android questions in June 2012

Why aren't getters preferred when accessing variables between activities?

14 votes

Daily there are many questions of the following type on SO:

How do I get a variable from another Activity?

The answers usually recommend to use SharedPreferences or Intent.putExtra().

To me, a getter method is what would be an approach to access a variable from another class. After all, the Activity that is under consideration is a class, and it's variables are class members.

Why aren't getter methods preferred to approaches like SharedPreferences or Intent extras?

I'm talking about simple situations that require accessing a variable between activities, for example this one:

class OneClass extends Activity {
    int a;

    ..
    // some changes to a
    ..
}

And then in another class(Activity):

class SomeOtherClass extends Activity {
    ..
    // trying to access a here
    ..
}

Is a getter method a correct approach here, or not?

Again - I'm not talking about scenarios where these things are actually the right way to go. SharedPreferences for persistent storage of small amount of data, extras as the documentation says : This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.


As some of the answers have likely indicated that there are certain scenarios like no guarantee of the other Activity being alive, I guess there are more probable and correct reasons as to why people suggest going for intents and shared preferences.

The answer to your question is two fold:

  • For the meta aspect, which belongs on meta SO anyway, many newbie programmers see Android, want to write apps, and suck at Java.
  • For the other quesiton, typically using a getter and setter won't work, because you can't pass objects between Activities in a straightforward way. While you can technically do this with a Parcelable, it's not recommended, and the better way is to use an intent to pass data between application components.
  • Another point this highlights is that Android apps should keep a minimal amount of state inside components. I think this has been a big success of Android. If you look at apps out there, there is on average a lot less global state than typical programs written in java. The programs are also smaller, which is to be expected, but the fact that an atomic activity can represent the state of a single screen, and the fact that any single screen won't typically be persisting that much state across the entire app, leads to an good logical separation between app components.

Why calling Process.killProcess(Process.myPid()) is a bad idea?

13 votes

I've read some posts saying using this method is "not good", shouldn't been use, it's not the right way to "close" the application and it's not how android works...

I understand and accept the fact that Android OS knows better then me when it's the right time to terminate the process, but I didn't heard yet a good explanation why it's wrong using the killProcess() method?. After all - it's part of the android API...

what I do know is that calling this method while other threads doing in potential an important work (operations on files, writing to DB, HTTP requests, running services..) can be terminated in the middle, and it's clearly not good. also I know I can benefit from the fact that "re-open" the application will be faster, cause the system maybe still "holds" in memory state from last time been used, and killProcess() prevents that.

Besides this reason, assuming I don't have such operations, and I don't care my application will load from scratch each run, there are other reasons why not using the killProcess() method?

I know about finish() method to close an Activity, so don't write me about that please.. finish() is only for Activity. not to all application, and I think I know exactly why and when to use it...

And another thing - I'm developing also games with the Unity3D framework, and exporting the project to android. When I decompiled the generated apk, I was very suprised to find out that the java source code created from unity - implementing Unity's - Application.quit() method, with Process.killProcess(Process.myPid()).

Application.quit() is suppose to be the right way to close game according to Unity3d guides (is it really? maybe I am wrong, and missed something), so how it happens that the Unity's framework developers which doing a very good work as it seems implemented this in native android to killProcess()?

Who said calling Process.killProcess(Process.myPid()) is a bad idea?

Yes, letting the OS manage its own memory is the best practice for both you and the user using your application (faster to open again, less chances for force closes, etc...).

However, assuming you know for sure that you're not interrupting threads or other background operations and you use this call in onDestroy() - I see no reason why you shouldn't use it. Especially when it's an API call and not a workaround, and Google didn't mention it's better not to use it in the API documentation.

Android App not compatible with devices that sideload Google Play

12 votes

I have an app which has been deployed to Play and is compatible with any device running 2.1 or later; no special restrictions or requirements defined in AndroidManifest.xml.

There have been several complaints from users trying to install the app via Google Play but getting messages that it is not compatible. In all of these cases sideloading the app works perfectly.

Digging a little deeper into the problem it appears that in all cases, the people reporting the problem are using a device that did not ship with Google Play installed. IE. the device probably failed Google's CTS.

Having said that, they are able to install other apps via Google Play but not ours. Again, sideloading our app onto these devices works fine. Does anybody know why this might be? I assume it must be something I am doing incorrectly in AndroidManifest.xml but I see nothing suspicious.

EDIT: Here's the AndroidManifest.xml, altered to protect the names of the innocent:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.foo.bar"
      android:versionCode="1"
      android:versionName="@string/global_app_version">
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="10"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application android:label="@string/global_app_short_name" android:icon="@drawable/app">
        <activity android:name=".HomeActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity android:name=".AActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <activity android:name=".BActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <activity android:name=".CActivity"
                  android:launchMode="singleTask"
                  android:theme="@android:style/Theme.Black.NoTitleBar"
                  android:windowSoftInputMode="stateHidden">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <activity android:name=".DActivity"
                  android:launchMode="singleTask"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <activity android:name=".EActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <activity android:name=".FActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>

        <!-- This activity is invoked whenever an xxx is opened -->
        <activity android:name=".GActivity"
                  android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter android:label="@string/global_app_short_name">
                <action android:name="android.intent.action.VIEW"/>
                <action android:name="android.intent.action.EDIT"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:mimeType="application/xxx"/>
                <data android:mimeType="application/yyy"/>
                <data android:mimeType="application/zzz"/>
                <data android:mimeType="application/aaa"/>
                <data android:mimeType="application/bbb"/>
            </intent-filter>
        </activity>
    </application>
</manifest> 

I believe found the culprit - Copy Protection was enabled. From Google's notes on the setting: http://developer.android.com/guide/google/play/filters.html

To copy protect an application, set copy protection to "On" when you configure publishing options for your application. Google Play will not show copy-protected applications on developer devices or unreleased devices.

That would definitely explain it! Just waiting for the setting to take effect so I can verify the fix.

At first I dismissed this as a possibility because the app was initially launched with the feature disabled. Has anybody else had this setting spontaneously revert on their app!?

UPDATE - Confirmed that this resolved the problem.

Fetch dial number while calling.

11 votes

When I enter any number in keypad and after when I press call button before the phone make call, I want to get that dial number in logcat.

See below Image for understand.

enter image description here

Can I get the number at the time of calling, if yes then How can I?

Hey Finally i got solution for that.. like this you can also get that.

You have to use ITelephony.aidl file Like this:

package com.android.internal.telephony;

import android.os.Bundle;
        interface ITelephony {
        boolean endCall();
        void dial(String number);
        void answerRingingCall();
        void abortCall();
    }

And In OutgoingCallReceiver

public class OutgoingCallReceiver extends BroadcastReceiver {

    Context context = null;
    private static final String TAG = "Phone call";
    private ITelephony telephonyService;

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();

        if (null == bundle)
            return;

        String phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

        Log.i("OutgoingCallReceiver", phonenumber);
        Log.i("OutgoingCallReceiver", bundle.toString());

        String info = "Detect Calls sample application\nOutgoing number: "+ phonenumber;
        /* System.out.println("value id:"+info); */
        Toast.makeText(context, info, Toast.LENGTH_LONG).show();

        TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        try {
            Class c = Class.forName(telephony.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);
            /*
             * com.android.internal.telephony.ITelephony telephonyService =
             * (ITelephony) m.invoke(tm);
             */
            telephonyService = (ITelephony) m.invoke(telephony);
            telephonyService.answerRingingCall();
            telephonyService.endCall();
            telephonyService.dial(null);
            telephonyService.abortCall();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

And if you want to get IncomingCallReceiver then Like this you can:

public class IncomingCallReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();

            if(null == bundle)
                    return;

            Log.i("IncomingCallReceiver",bundle.toString());
            String state = bundle.getString(TelephonyManager.EXTRA_STATE);
            Log.i("IncomingCallReceiver","State: "+ state);
            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
            {
                    String phonenumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                    Log.i("IncomingCallReceiver","Incomng Number: " + phonenumber);
                    System.out.println("Coming in Incoming Number"+phonenumber);
                    String info = "Detect Calls sample application\nIncoming number: " + phonenumber;
                    Toast.makeText(context, info, Toast.LENGTH_LONG).show();
            }
    }

}

And ya Guys don't forget to add Permission in AndroidManifest file :

 <receiver android:name="com.varma.samples.detectcalls.receivers.OutgoingCallReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.varma.samples.detectcalls.receivers.IncomingCallReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />

Error in KSOAP Parsing :- java.lang.ClassCastException: org.ksoap2.SoapFault

10 votes

I have a little knowledge in ksoap Parsing. When i am parsing some data it gives Error :

java.lang.ClassCastException: org.ksoap2.SoapFault

I can see the response for that method in SoapUI but when i parsing that method in android it gives an error as like above.

Here is Request parameter as input in SoapUI

        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
        <soapenv:Header/>
        <soapenv:Body>
           <tem:SaveChangePasswordForExternalUser>
              <tem:userId>Test123</tem:userId>
              <!--Optional:-->
              <tem:oldPassword>TestTest</tem:oldPassword>
              <!--Optional:-->
              <tem:newPassword>Test</tem:newPassword>
              <!--Optional:-->
              <tem:retypedNewPassword>Test</tem:retypedNewPassword>
           </tem:SaveChangePasswordForExternalUser>
        </soapenv:Body>
     </soapenv:Envelope>

Here Is Response i got in SoapUI

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
         <faultstring xml:lang="en-US">Old Password was incorrectly entered. Remember that passwords are case-sensitive.</faultstring>
         <detail>
            <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
               <HelpLink i:nil="true"/>
               <InnerException i:nil="true"/>
               <Message>Old Password was incorrectly entered. Remember that passwords are case-sensitive.</Message>       
               <Type>System.Web.Services.Protocols.SoapException</Type>
            </ExceptionDetail>
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

This how i try to get the response by code in android

public void getData()
    {

        private static final String NAMESPACE = "http://tempuri.org/"; //
        private static final String URL = "http://173.203.136.194:99/LeaseWave.MobileApplication.Service/MobileApplicationService.svc/basic";
        private static final String SOAP_ACTION = "http://tempuri.org/IMobileApplicationService/SaveChangePasswordForExternalUser";
        private static final String METHOD_NAME = "SaveChangePasswordForExternalUser";

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
        request.addProperty("userId", "Test123");
        request.addProperty("oldPassword", "TestTest");
        request.addProperty("newPassword", "Test");
        request.addProperty("newPassword", "Test");

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        try {

            androidHttpTransport.call(SOAP_ACTION, envelope);
            SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;

            Log.i("Long...", "Response  ------ "+resultsRequestSOAP);


        }catch (Exception e)
        {
            e.printStackTrace();
        }

    }

but i don't get success in that. Anyone have any kind of hint or solution for this?

This sort of code can solve your problem,

    if (envelope.bodyIn instanceof SoapFault) {
        String str= ((SoapFault) envelope.bodyIn).faultstring;
        Log.i("", str);

        // Another way to travers through the SoapFault object
    /*  Node detailsString =str= ((SoapFault) envelope.bodyIn).detail; 
        Element detailElem = (Element) details.getElement(0) 
                     .getChild(0); 
        Element e = (Element) detailElem.getChild(2);faultstring; 
        Log.i("", e.getName() + " " + e.getText(0)str); */
    } else {
        SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
        Log.d("WS", String.valueOf(resultsRequestSOAP));
    }

Why start using -libraryjars when I never needed it before?

9 votes

Since I updated ADT from 16 to 18 (which mandated Proguard update from 4.6 to 4.8), Proguard has been acting very weirdly (and inconsistently?).

The latest such problem is when I try to export a signed (release) APK, I receive the following errors:

Proguard returned with error code 1. See console
Warning: com.bta.LibProj2: can't find referenced class com.bta.R$string
Warning: com.bta.MyDlg1: can't find referenced class com.bta.R$string
Warning: com.bta.MyMenu: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$attr
Warning: com.bta.R: can't find referenced class com.bta.R$drawable
Warning: com.bta.R: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$string
Warning: com.bta.myapp.MyAppActivity$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$ELicenseResponse: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.R$array: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$layout: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$xml: can't find referenced class com.bta.myapp.R
Warning: there were 49 unresolved references to classes or interfaces.
         You may need to specify additional library jars (using '-libraryjars').
java.io.IOException: Please correct the above warnings first.
    at proguard.Initializer.execute(Initializer.java:321)
    at proguard.ProGuard.initialize(ProGuard.java:212)
    at proguard.ProGuard.execute(ProGuard.java:87)
    at proguard.ProGuard.main(ProGuard.java:493)

I did notice the recommendation to add -libraryjars in proguard.cfg, but I never needed to do this before (and I didn't change anything in my code, all I did was updating Proguard from 4.6 to 4.8). Does this suggest something wrong in my development environment configuration?

Also, I checked Proguard's Troubleshooting section for Can't find referenced class: It refers to forgetting or ignoring to specify a library via -libraryjars (which I admit), but I never specified any library and it always worked before! What changed?

My proguard.cfg file BTW starts with:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

Any idea what's going on? Why did Proguard start giving me such hard time? (I coasted very smoothly with it for over a year now) Is there something fundamental I am missing in my system configuration?

BTW, I did try to add the libraries I have been using by specifying all of them in -libraryjars lines, but Proguard's behavior only got worse: It would fail without giving any of the error log that I quoted above.

Problem solved. After much search for clues here in SO, I finally found this hint by no other than Proguard's developer himself:

-dontwarn scala.**

I'm not using anything that contains "scala" and I don't know what scala is. But that gave me the idea of placing a -dontwarn on my own application package:

-dontwarn com.bta.**

That did the trick.

For the record, the search phrase that led me to finding this hint was: proguard admob "can't find referenced class".

P.S. Proguard's suggestion You may need to specify additional library jars (using '-libraryjars') wasn't even in the right direction...

UPDATE: While -dontwarn com.bta.** allowed producing a signed APK, it crashed as soon as I tried to launch it with:

ClassNotFoundException: com.bta.myapp.MyAppActivity in loader dalvik.system.PathClassLoader[/data/app/com.bta.myapp.myapp-1.apk]. 

What a nightmare.

UPDATE 2: -dontwarn com.bta.** turned out to be way too inclusive. I changed it to:

-dontwarn com.bta.myapp.MyAppActivity.R**

And now everything runs well without incident. What a nightmare.

After wasting way too much time on debugging the very tools that are supposed to save me time, I discovered the source of the problem. It's a bug in the Android SDK tools. It is documented as have been solved in r17, but I am using the latest of today (June 18 2012) and it hasn't been solved! (see comment 24). Comment 25 also describes the workaround that allows me now to proceed with my actual development.

Bugs are fact of life in complex systems. But the fact that neither Proguard nor the build tools that feed input to Proguard could provide any helpful error message (in fact they did exactly the opposite), suggests something is broken in the "methodology" of the Android development tools recommended by Google.

Eclipse keeps Building workspace... and Building workspace... and Building workspace

9 votes

Why would Eclipse, when building an Android project, get stuck in an infinite loop for Building workspace... and (re) Building workspace... and (re) Building workspace...

Is this a known bug?

What is the proper way to get out of this loop?

Notes:

  1. If I uncheck Project > Build Automatically, it builds fine and even exports a perfectly running signed release APK.
  2. This problem only started after I upgraded to the latest SDK r19. Prior to that (SDK r11) I never experienced this problem.
  3. Bug 160868 describes exactly this problem. But hasn't it being solved since then?
  4. A similar problem description found here but like the previous one, it's old and not directly related to Android development.
  5. Issue 27940 suggests a bug in handling a const named BuildConfig.DEBUG which may or may not be related. But hasn't it been fixed in r18???
  6. I found this great tip for auto tagging / date-stamping in the Android build system, but I am not using anything like that, in addition to double-checking and verifying that builders come at the right order the Project builders list order (same order as other projects that do not exhibit this infinite-loop build behavior).
  7. My hunch tells me there might be a lock-file or flag that somehow got stuck (read-only mode?) and thus confuses the build system. Any idea what that boolean may be and where to find it?
  8. If I first open another project in the same workspace (that doesn't exhibit this problem), the project that has this problem miraculously stops the infinite rebuilding. This doesn't happen if I reverse the order of which project is opened first. Does this imply gremlins in the Eclipse/SDK/ADT build system?

No "blind shooting" please: answer this question only if you have personally experienced this amazing phenomenon (and solved it) or can point to an article that experienced this amazing phenomenon (and solved it).

Turns out bug 27940 hasn't been fixed yet.

I use the following workaround:

  1. Disable "Project > Build Automatically"
  2. Project > Clean
  3. Project > Build All

Android Activity ClassNotFoundException - tried everything

8 votes

I've just refactored an app into a framework library and an application, but now when I try and start the app in the emulator I get the following error stack trace:

06-02 18:22:35.529: E/AndroidRuntime(586): FATAL EXCEPTION: main
06-02 18:22:35.529: E/AndroidRuntime(586): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.matthewrathbone.eastersays/com.matthewrathbone.eastersays.EasterSimonSaysActivity}: java.lang.ClassNotFoundException: com.matthewrathbone.eastersays.EasterSimonSaysActivity in loader dalvik.system.PathClassLoader[/data/app/com.matthewrathbone.eastersays-1.apk]
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.os.Handler.dispatchMessage(Handler.java:99)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.os.Looper.loop(Looper.java:123)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread.main(ActivityThread.java:4627)
06-02 18:22:35.529: E/AndroidRuntime(586):  at java.lang.reflect.Method.invokeNative(Native Method)
06-02 18:22:35.529: E/AndroidRuntime(586):  at java.lang.reflect.Method.invoke(Method.java:521)
06-02 18:22:35.529: E/AndroidRuntime(586):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-02 18:22:35.529: E/AndroidRuntime(586):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-02 18:22:35.529: E/AndroidRuntime(586):  at dalvik.system.NativeStart.main(Native Method)
06-02 18:22:35.529: E/AndroidRuntime(586): Caused by: java.lang.ClassNotFoundException: com.matthewrathbone.eastersays.EasterSimonSaysActivity in loader dalvik.system.PathClassLoader[/data/app/com.matthewrathbone.eastersays-1.apk]
06-02 18:22:35.529: E/AndroidRuntime(586):  at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
06-02 18:22:35.529: E/AndroidRuntime(586):  at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
06-02 18:22:35.529: E/AndroidRuntime(586):  at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
06-02 18:22:35.529: E/AndroidRuntime(586):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
06-02 18:22:35.529: E/AndroidRuntime(586):  ... 11 more

Usually this means that the manifest file is wrong in some way, but I've double checked everything I can think of.

Here is my activity class:

package com.matthewrathbone.eastersays;

import android.os.Bundle;

import com.rathboma.simonsays.Assets.Season;
import com.rathboma.simonsays.SeasonPicker;
import com.rathboma.simonsays.SimonSaysActivity;

    public class EasterSimonSaysActivity extends SimonSaysActivity {

      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      }

      @Override
      protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
      }

      @Override
      public SeasonPicker getSeasonPicker() {
       return new SeasonPicker(){
        @Override
        public Season getSeason() {
          // TODO Auto-generated method stub
          return Season.EASTER;
        }
       };
      }
    }

As you can see, it's listed correctly in the manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.matthewrathbone.eastersays"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".EasterSimonSaysActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I have no idea how to fix this, and would appreciate any help. I've scanned many similar questions on SO without seeing this particular behavior.

More info:

  • I've checked inside the generated APK and the class has an entry in the classes.dex file
  • I've tried cleaning/building the project in eclipse
  • I've tried using a totally new device image that doesn't have a copy of the APK on it already
  • I've changed the library project into a regular java, then changed back into an android project, no difference
  • Adding the abstract SimonSaysActivity to the manifest makes no difference.
  • I've tried making every dependency an android library project, and syncing the android version that they require, it did not help

Found the solution (see below). To everyone that posted an answer / comment: You all rock, thanks for helping me work through the problems!

Looks like this is introduced by an SDK tools upgrade. Thanks to @Nick below in the comments for this link: http://iqadd.com/item/noclassdeffounderror-adt-fix

I spent some time play with my own project, and I am able to replicate your problem and get exactly the same exception stack trace when trying to run my main project, so I think this could be the cause:

Just like what I thought, it is all about how you reference your Android library project in the Android main project, a simple Eclipse configuration settings.

The Wrong Way:
Right click main project, choose Properties -> Java Build Path -> Projects -> Add..., this add the Android library Project as a dependency project in Android main project's build path, this does not work. If all required Android-related resources are defined in main project, you will not get any error at compile time, but when run the application, you get the exception described in the question.

The Correct Way:
Right click main project, choose Properties -> Android, in the Library section, add your Android library project here. Check out official dev guide Referencing a library project. This should fix all your problem. Also note that you have to use relative path reference the actual Android library project, as stated in the Library Project - Development considerations.

Hope this helps.

android finish current activity causes app close

8 votes

I am executing maswebview class and I would like to finish only this activity. I tried maswebview.this.finish() but when executed, app is been closed. Then if I set a new view for the tab content, it is loaded properly and webviewmas dissapears but just for a while, then appears again fitting fullscreen. How to finish maswebview completely? ThanK you

public void onClick(View arg0) 
            {
                /*
                Intent intent = getIntent();
                intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
                startActivityForResult(intent, 1);
                Intent intentmas = new Intent (maswebview.this, mas.class);
                intentmas.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 
                intentmas.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
                intentmas.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
                intentmas.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                View vista = getLocalActivityManager().startActivity("maswb", intentmas).getDecorView();
                setContentView(vista);  */

                maswebview.this.finish();

Do you have any other activities of your app in the stack by the time you call finish()? If you don't, you'll want to start the desired activity instead of finishing the current one.

But actually it seems to me that you're trying to accomplish something that can be done simpler. Can you provide more info on the task at hand and your app structure you're trying to go about it with?

From what you said, it seems like you have tabbed UI and you're trying to show a webview in one of the tabs, then hide it.

First, I don't see why you want the webview in a separate activity. Seems to me you could just have it in layout of one of the tabs and just call setVisibility(GONE) to hide it.

Second - and this is important - looks like you're trying to implement tabs the old way - TabWidget, TabHost, etc. Since Honeycomb has been released, there's much more convenient way to implement tabbed UI - Action Bar Tabs and Fragments - that approach is much more convenient and will render your webview problems obsolete: there's a thing called WebViewFragment which is basically a WebView but smarter - it will handle its own lifecycle with minimum effort required from you (i.e. pause when removed, resume when added). It will take some effort to study up on Fragments, but it's well worth it. You can get Fragments API for pre-Honeycomb android sdks as a static library - it's called android-support-v4 and you can download it in Android SDK Manager.

How did they make such layout - which elements they used?

8 votes

At the moment, I am using Euro 2012 app and it has some interesting layout parts. If you go to matches->knockout screen, you'll see 3 screens like this.

If you slide left or right, you move between them not like between one activity to another, but just like all these elements are laid on one big canvas and you slide each screen into focus. Even thou, if you slide left/right, the screen cannot be stopped in the way that half of each image is visible, so I guess it's not a big canvas. Somehow you can slide screen like one big image, and yet it always lock perfectly as if they used 3 activities for this.

How did the do this?

It's a ViewPager, available in Android support package and described in their blog.

In C, tan(30) gives me a negative value! Why?

8 votes

I observe that my tan(float) function from the cmath library is returning a negative value.

The following piece of code, when run :

    #include <cmath>
    ....

    // some calculation here gives me a value between 0.0 to 1.0.
    float tempSpeed = 0.5; 

    float tanValue = tan(tempSpeed * 60);

    __android_log_print(ANDROID_LOG_INFO, "Log Me", "speed: %f", tanValue);

Gives me this result in my Log file:

    Log Me: speed `-6.4053311966`

As far as I remember

    tan(0.5*60) = tan(30) = 1/underoot(3);

Can someone help me here as in why I am seeing a negative value? Is it related to some floating point size error? Or am I doing something really dumb?

In C, tan and other trigonometric functions expect radians as their arguments, not degrees. You can convert degrees to radians:

tan( 30. * M_PI / 180. ) == 0.57735026918962576450914878050196