【问题标题】:JavaScript Interface not working in my Android ApplicationJavaScript 接口在我的 Android 应用程序中不起作用
【发布时间】:2023-03-08 23:25:01
【问题描述】:

以下是我的 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 。

有人可以说明一下我的代码有什么问题以及为什么 Javascript 界面不适合我。

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

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

我忘记提到的一个 IMP 事情是,我正在笔记本电脑浏览器上通过简单地使用 file: 协议加载 HTML 文件来测试它。 这有关系吗?

【问题讨论】:

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


    【解决方案1】:
    window.localStorage=LocalStorage; 
    

    上面的代码表示窗口对象具有名为localStorage 的属性,并且您尝试将其值设置为LocalStorageLocalStorage 由 android 为您创建的对象可以保证,但最终 localStorage 窗口对象的属性没有保证。所以抛出异常。希望这个答案对你有帮助。

    【讨论】:

    • 您是在暗示窗口没有名为 localStorage 的属性吗?甚至在此更改之前,我就在使用 localStorage.... 所以我很困惑
    • 我在我的三星笔记 Android 4.1.2 上测试了这段代码,我在 localStorage 中添加了一些项目并重新启动手机,localStorage 数据消失了:(有人可以帮我吗
    • 首先设置javascript启用标志,然后将javascript接口添加到webview。
    • @ShantanooK window.localStorage=LocalStorage 你不能这样做。窗口对象中没有名为 localStorage 的属性。
    • 那我该怎么办,而且我在访问 window.localStorage 时也没有遇到任何问题,唯一的例外是未定义 LocalStorage
    【解决方案2】:

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

    原始代码

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

    修改代码

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多