Android, Logcat gives error about SearchView class

2019-02-14 07:29发布

问题:

i have installed the support library to get the action bar worked also in android pre API 11

When i start the application, the logcat give this error:

08-20 19:54:41.600: I/dalvikvm(9828): Failed resolving Landroid/support/v7/widget/SearchView$5; interface 809 'Landroid/view/View$OnLayoutChangeListener;'

08-20 19:54:41.600: W/dalvikvm(9828): Link of class 'Landroid/support/v7/widget/SearchView$5;' failed

08-20 19:54:41.600: E/dalvikvm(9828): Could not find class 'android.support.v7.widget.SearchView$5', referenced from method android.support.v7.widget.SearchView.addOnLayoutChangeListenerToDropDownAnchorSDK11

08-20 19:54:41.600: W/dalvikvm(9828): VFY: unable to resolve new-instance 734 (Landroid/support/v7/widget/SearchView$5;) in Landroid/support/v7/widget/SearchView;

08-20 19:54:41.600: D/dalvikvm(9828): VFY: replacing opcode 0x22 at 0x0002

08-20 19:54:41.600: D/dalvikvm(9828): VFY: dead code 0x0004-000a in Landroid/support/v7/widget/SearchView;.addOnLayoutChangeListenerToDropDownAnchorSDK11 ()V

Can someone help me, i search around the web but i found nothing. Thank you

MainActivity.Java

    package com.example.fanculo;

    import android.os.Bundle;
    import android.app.SearchManager;
    import android.content.Context;
    import android.support.v4.view.MenuItemCompat;
    import android.support.v7.widget.SearchView;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.ActionBarActivity;
    import android.view.Menu;
    import android.view.MenuItem;


    public class MainActivity extends ActionBarActivity{

ActionBar actionBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    actionBar = getSupportActionBar();
    actionBar.setTitle("Test");

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

     SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    // Configure the search info and add any event listeners
     searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
     searchView.setIconifiedByDefault(true); 
    return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            onSearchRequested();
            return true;
        default:
            return false;
    }
}

}

回答1:

I think this is a bug in SearchView.java class in support library, you can see that it is using View.OnLayoutChangeListener in a common implementation file:

https://android.googlesource.com/platform/frameworks/support.git/+/android-4.3_r1/v7/appcompat/src/android/support/v7/widget/SearchView.java

this makes class loader to try loading View.OnLayoutChangeListener which is available since api level 11 - even if this *SDK11 method is not even called. I suppose this method addOnLayoutChangeListenerToDropDownAnchorSDK11 should be moved to external java class and used only if device API is >= 11.

You can reproduce this bug copying this code to your own activity:

private void addOnLayoutChangeListenerToDropDownAnchorSDK11() {
    new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom,
                                   int oldLeft, int oldTop, int oldRight, int oldBottom) {
        }
    };
}

public void onCreate(...) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            addOnLayoutChangeListenerToDropDownAnchorSDK11();
        }
}

below is what logcat prints:

08-31 22:50:33.030: INFO/dalvikvm(20753): Failed resolving Lcom/example/ActionBarTester/MyActivity$1; interface 813 'Landroid/view/View$OnLayoutChangeListener;'
08-31 22:50:33.030: WARN/dalvikvm(20753): Link of class 'Lcom/example/ActionBarTester/MyActivity$1;' failed
08-31 22:50:33.030: ERROR/dalvikvm(20753): Could not find class 'com.example.ActionBarTester.MyActivity$1', referenced from method com.example.ActionBarTester.MyActivity.addOnLayoutChangeListenerToDropDownAnchorSDK11
08-31 22:50:33.030: WARN/dalvikvm(20753): VFY: unable to resolve new-instance 903 (Lcom/example/ActionBarTester/MyActivity$1;) in Lcom/example/ActionBarTester/MyActivity;
08-31 22:50:33.030: DEBUG/dalvikvm(20753): VFY: replacing opcode 0x22 at 0x0000
08-31 22:50:33.030: DEBUG/dalvikvm(20753): VFY: dead code 0x0002-0005 in Lcom/example/ActionBarTester/MyActivity;.addOnLayoutChangeListenerToDropDownAnchorSDK11 ()V

I am not sure if this bug Is actually causing any problems, in my case SearchView works on API Level 10, also above tests allow my activity to work. Maybe I am missing something here.



回答2:

How about using ActionBarSherlock?? It's flexible and support older versions as well and also it's very easy to implement.

All you have to do is to switch every class you're extending Activity in To SherlockActivity and Also fragment. I advice you to try it! https://github.com/JakeWharton/ActionBarSherlock



回答3:

You need to ensure you add the Android V7 Support Library correctly in Eclipse to remove the following error from the log 'Could not find class android.support.v7.widget.SearchView$5 referenced from method android.support.v7.widget.SearchView.addOnLayoutChangeListenerToDropDownAnchorSDK11'.

The key thing to remember, don't forget to uncheck Android Dependencies when adding the Support Library because the v7 appcompat library has resources. After making the change to your dependencies in your support library project, clean the support library project and that's it.

Refer to complete procedure in section Adding Libraries with Resources of official Google doco on how to add support libraries with resources.

Excerpt from above referenced doco in case link changes in future:

  1. Make sure you have downloaded the Android Support Library using the SDK Manager.
  2. Create a library project and ensure the required JAR files are included in the project's build path:
    • Select File > Import.
    • Select Existing Android Code Into Workspace and click Next.
    • Browse to the SDK installation directory and then to the Support Library folder. For example, if you are adding the appcompat project, browse to /extras/android/support/v7/appcompat/.
    • Click Finish to import the project. For the v7 appcompat project, you should now see a new project titled android-support-v7-appcompat.
    • In the new library project, expand the libs/ folder, right-click each .jar file and select Build Path > Add to Build Path. For example, when creating the the v7 appcompat project, add both the android-support-v4.jar and android-support-v7-appcompat.jar files to the build path.
    • Right-click the project and select Build Path > Configure Build Path. In the Order and Export tab, check the .jar files you just added to the build path, so they are available to projects that depend on this library project. For example, the appcompat project requires you to export both the android-support-v4.jar and android-support-v7-appcompat.jar files.
    • Uncheck Android Dependencies.
    • Click OK to complete the changes.