JavaScript界面​​在我的Android应用程序中无效

时间:2014-01-23 03:17:35

标签: javascript android html5 android-webview local-storage

以下是我的MainActivity类代码

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.activity_main);
    WebView webView = new WebView(this);

    //add the JavaScriptInterface so that JavaScript is able to use LocalStorageJavaScriptInterface's methods when calling "LocalStorage"
    webView.addJavascriptInterface(new LocalStorageJavaScriptInterface(this), "LocalStorage");

    WebSettings settings = webView.getSettings();
    // TO enable JS
    settings.setJavaScriptEnabled(true);
    // To enable Localstorage
    settings.setDomStorageEnabled(true);

    //those two lines seem necessary to keep data that were stored even if the app was killed.
    settings.setDatabaseEnabled(true);
 /*   
    webView.setWebChromeClient(new WebChromeClient() { 
        public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { 
                quotaUpdater.updateQuota(5 * 1024 * 1024); 
            } 
        });*/

    //load HTML File in webview
    webView.loadUrl("file:///android_asset/main.html");

    setContentView(webView);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
  //  getMenuInflater().inflate(R.menu.main, menu);
    return true;
}


/**
 * This class is used as a substitution of the local storage in Android webviews
 * 
 * @author Diane
 */
public class LocalStorageJavaScriptInterface {
        private Context mContext;
        private LocalStorage localStorageDBHelper;
        private SQLiteDatabase database;

        LocalStorageJavaScriptInterface(Context c) {
                mContext = c;
                localStorageDBHelper = LocalStorage.getInstance(mContext);
        }

        /**
         * This method allows to get an item for the given key
         * @param key : the key to look for in the local storage
         * @return the item having the given key
         */
        @JavascriptInterface
        public String getItem(String key)
        {
                String value = null;
                if(key != null)
                {
                        database = localStorageDBHelper.getReadableDatabase();
                        Cursor cursor = database.query(LocalStorage.LOCALSTORAGE_TABLE_NAME,
                                        null, 
                                        LocalStorage.LOCALSTORAGE_ID + " = ?", 
                                        new String [] {key},null, null, null);
                        if(cursor.moveToFirst())
                        {
                                value = cursor.getString(1);
                        }
                        cursor.close();
                        database.close();
                }
                return value;
        }

        /**
         * set the value for the given key, or create the set of datas if the key does not exist already.
         * @param key
         * @param value
         */
        @JavascriptInterface
        public void setItem(String key,String value)
        {
                if(key != null && value != null)
                {
                        String oldValue = getItem(key);
                        database = localStorageDBHelper.getWritableDatabase();
                        ContentValues values = new ContentValues();
                        values.put(LocalStorage.LOCALSTORAGE_ID, key);
                        values.put(LocalStorage.LOCALSTORAGE_VALUE, value);
                        if(oldValue != null)
                        {
                                database.update(LocalStorage.LOCALSTORAGE_TABLE_NAME, values, LocalStorage.LOCALSTORAGE_ID + " = " + key, null);
                        }
                        else
                        {
                                database.insert(LocalStorage.LOCALSTORAGE_TABLE_NAME, null, values);
                        }
                        database.close();
                }
        }

        /**
         * removes the item corresponding to the given key
         * @param key
         */
        @JavascriptInterface
        public void removeItem(String key)
        {
                if(key != null)
                {
                        database = localStorageDBHelper.getWritableDatabase();
                        database.delete(LocalStorage.LOCALSTORAGE_TABLE_NAME,   LocalStorage.LOCALSTORAGE_ID + " = " + key, null);
                        database.close();
                }
        }

        /**
         * clears all the local storage.
         */
        @JavascriptInterface
        public void clear()
        {
                database = localStorageDBHelper.getWritableDatabase();
                database.delete(LocalStorage.LOCALSTORAGE_TABLE_NAME, null, null);
                database.close();
        }
}

}

基本上我使用的是AndroidLocalstorage插件https://github.com/didimoo/AndroidLocalStorage,它基本上用作localStorage的后备选项。

以下是我的AndroidMainifest.xml

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

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>



    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.android_playlist.MainActivity"
            android:label="@string/app_name" 
            android:screenOrientation="portrait"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

    </application>

    </manifest>

基本上问题是javascriptInterface对我不起作用。

我在我的js文件中添加了以下代码行,用于加载

try{
    //we replace default localStorage with our Android Database one
    window.localStorage=LocalStorage;    
}catch(e){
    //LocalStorage class was not found. be sure to add it to the webview
        console.log("error", e);
        console.log("LocalStorage ERROR : can't find android class LocalStorage. switching to raw localStorage")              
   }

但是当我检查浏览器控制台时,我总是得到console.log,它位于catch。

有人可以说明我的代码有什么问题以及为什么Javascript界面​​对我不起作用。

以下是我在控制台中收到的错误

{stack: (...), message: "LocalStorage is not defined"} 

我忘了提到的一件事是我在笔记本电脑浏览器上测试这个,只需使用file:protocol加载HTML文件即可。 这有关系吗?

2 个答案:

答案 0 :(得分:0)

window.localStorage=LocalStorage; 

上面的代码表示window对象具有名为localStorage的属性,并且您尝试将其值设置为LocalStorage。由android创建的LocalStorage对象,可以保证但最终localStorage属性为窗口对象没有保证。因此引发异常。希望这个ans会帮助你。

答案 1 :(得分:0)

我终于在我的代码中发现了这个问题,在AndroidMainifest XML中,我的targetSDK版本是18。 它应该是19,因为我没有在MainActivity中设置数据库路径和数据库大小。

原始代码

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="18" />

更改了代码

<uses-sdk 
    android:minSdkVersion="14" 
    android:targetSdkVersion="19" />