অ্যান্ড্রয়েড ওয়েবভিউ: পরিচালনা ওরিয়েন্টেশন পরিবর্তন


147

ইস্যুটি রোটেশনের পরে কর্মক্ষমতা। ওয়েবভিউকে পৃষ্ঠাটি পুনরায় লোড করতে হবে যা কিছুটা ক্লান্তিকর হতে পারে।

প্রত্যেকবার পৃষ্ঠা থেকে উত্সটি পুনরায় লোড না করে ওরিয়েন্টেশন পরিবর্তন পরিচালনা করার সর্বোত্তম উপায় কী?


3
"উত্স থেকে পুনরায় লোড" এর অর্থ আপনি কী আবার পৃষ্ঠাটি ডাউনলোড করছেন, বা কেবল পুনরায় রেন্ডারিং করছেন?
জেরেমি লোগান

ব্ল্যাকহেক্স দ্বারা উল্লিখিত সমাধানটি আমার সমস্যার সমাধান করে।
Italo Borssatto

6
আমি আশ্চর্য হই যে আমার অ্যাপ্লিকেশনটি সম্পর্কে কী এতটা বিশেষ যে এই উত্তরগুলির
কোনওটিই কার্যকর হয় না

উত্তর:


91

আপনি যদি না চান তবে ওয়েবভিউ ওরিয়েন্টেশন পরিবর্তনের উপর পুনরায় লোড করতে চাইলে আপনার ক্রিয়াকলাপ শ্রেণিতে পরিবর্তনটি কনফিগারেশন-এ পরিবর্তিত হয়েছে:

@Override
public void onConfigurationChanged(Configuration newConfig){        
    super.onConfigurationChanged(newConfig);
}

এবং অ্যান্ড্রয়েড সেট করুন: ম্যানিফেস্টে কনফিগারচস অ্যাট্রিবিউট:

<activity android:name="..."
          android:label="@string/appName"
          android:configChanges="orientation|screenSize"

আরও তথ্যের জন্য দেখুন: http://developer.android.com/guide/topics/resources/runtime-changes.html# হ্যান্ডলিং দ্য
চেঞ্জ

https://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges


4
আমি পরীক্ষা করে দেখেছি কিন্তু কাজ করছে না, নীচের মতো কনফিগার চেঞ্জের বৈশিষ্ট্যটি কাজ করবে। android: configChanges = "কীবোর্ডহাইডান |
অভিমুখীকরণ

18
এটি করা নিরুৎসাহিত করা হয়েছে, যেমনটি আগেও বহুবার উল্লেখ করা হয়েছে
ম্যাথিয়াস

3
ম্যাথিয়াস: এটি সত্য নয় - ওয়েবভিউয়ের জন্য জাভাদোক দেখুন।
krtek

এই সমাধানটি সম্পর্কে দুটি বিষয় লক্ষণীয়: ১) আপনার যদি ওয়েবউউয়ের সাথে কোনও বিমূর্ত ক্রিয়াকলাপ থাকে configChangesতবে সাবক্লাস কার্যকলাপে বৈশিষ্ট্যটি যুক্ত হয় 2) যদি আপনার অ্যাপ্লিকেশন একাধিক প্রকল্পের উপর নির্ভর করে তবে configChangesবৈশিষ্ট্যটি এতে থাকা ব্যক্তির ম্যানিফেস্টে যুক্ত হয় নির্ভরতা গাছের শীর্ষে (যা ক্রিয়াকলাপ শ্রেণীর সমন্বিত প্রকল্প নাও হতে পারে)।
আমান্ডা এস

4
এই জাতীয় onConfigurationChangedপদ্ধতি ওভাররাইড অকেজো।
মিহা_এক্স 64৪

69

সম্পাদনা করুন: এই পদ্ধতিটি আর ডক্সে বর্ণিত হিসাবে কাজ করে না


আসল উত্তর:

এটি onSaveInstanceState(Bundle outState)আপনার ক্রিয়াকলাপে ওভাররাইটিং এবং ওয়েবভিউ saveStateথেকে কল করে পরিচালনা করা যেতে পারে :

   protected void onSaveInstanceState(Bundle outState) {
      webView.saveState(outState);
   }

তারপরে ওয়েবভিউ অবশ্যই পুনরায় স্ফীত হওয়ার পরে এটি আপনার অনক্রিতে পুনরুদ্ধার করুন:

public void onCreate(final Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.blah);
   if (savedInstanceState != null)
      ((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);
}

26
এটি ওরিয়েন্টেশন পরিবর্তনে কাজ করে না - ফাঁকা স্ক্রিন প্রদর্শিত হয়। saveState \ পুনরুদ্ধার স্টেট পদ্ধতিগুলি বলা হয় তবে এটি কোনও উপকার করে না
ওলেকসেই মালোভানই

1
এখানে অনক্রিট কোড স্নিপেট রয়েছে: সেটকন্টেন্টভিউ (আর .layout.webview); এমওয়েবভিউ = (ওয়েবভিউ) সন্ধান ভিউবিআইআইডি (আর.আইডি.উইউভিউ); যদি (saveInstanceState == নাল) {এমওয়েবভিউ.সেটসেটেটিংস ()। setJavaScriptEn اهل (সত্য); mWebView.setWebViewClient (নতুন সিম্পিউলভিউক্লিয়েন্ট ()); mWebView.loadUrl (Consts.URL_AUTHORIZATION_OAUTH); } অন্য {এমওয়েবভিউ.রেস্টোর স্টেট (সেভড ইনস্ট্যান্সস্টেট); }
ওলেকসেই মালোভানই

12
সেভস্টেটের ডকুমেন্টেশন থেকে: দয়া করে নোট করুন যে এই পদ্ধতিটি আর এই ওয়েবভিউয়ের জন্য প্রদর্শন ডেটা সঞ্চয় করে না। পূর্ববর্তী আচরণ সম্ভাব্য ফাইল লিক পারে ...
brillenheini

5
"দয়া করে নোট করুন যে এই পদ্ধতিটি আর এই ওয়েবভিউয়ের জন্য প্রদর্শন ডেটা সংরক্ষণ করে না" - বিকাশকারী.অ্যান্ড্রয়েড.
স্টিভেন মার্ক ফোর্ড

কোনও ওয়েবউইউ ফর্ম পুনরায় লোডিং রোধ করতে "এই পদ্ধতিটি এই ওয়েবভিউর জন্য প্রদর্শন ডেটা আর সংরক্ষণ করে না" এখন কী করার বিষয়ে কোনও পরামর্শ আছে?
লুকাস পি।

24

এর সর্বোত্তম উত্তরটি এখানে পাওয়া যায় অ্যান্ড্রয়েড ডকুমেন্টেশনগুলি অনুসরণ করা মূলত এটি ওয়েবভিউকে পুনরায় লোড করা থেকে বিরত রাখবে:

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize|layoutDirection|uiMode"
      android:label="@string/app_name">

Allyচ্ছিকভাবে , আপনি onConfigurationChangedক্রিয়াকলাপকে ওভাররাইড করে ব্যতিক্রমগুলি (যদি থাকে তবে) ঠিক করতে পারেন :

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

6
আপনার কনফিগারেশন চেঞ্জড () পদ্ধতিটির দরকার নেই আমি যথেষ্ট নিশ্চিত, ম্যানিফেস্টে কেবলমাত্র অতিরিক্ত বৈশিষ্ট্য। আমার অনুমান যে এর জন্য স্থানীয় সমর্থনটি ওয়েবভিউ সরবরাহ করেছিল এবং এ কারণেই এখন এই উত্তরটি সবচেয়ে ভাল (কারণ প্রশ্নটি মূলত যখন জিজ্ঞাসা করা হয়েছিল তখন এটি কার্যকর হয়নি)
বুগার

1
আমি @ বুগারকে অনুমোদন দিয়েছি যে আপনি onConfigrationChanged () পদ্ধতি ওভাররাইড করতে হবে না। আপনার সমস্ত প্রয়োজন অ্যান্ড্রয়েড যুক্ত করুন: কনফিগারেশন.এক্সএমএল ফাইলটিতে কনফিগারেশন = "ওরিয়েন্টেশন | স্ক্রিন সাইজ"।
ওজানুরকান

5

আমি ব্যবহার চেষ্টা করেছি onRetainNonConfigurationInstance (ফিরে ওয়েবদৃশ্য ), তারপর এটা পেয়ে ফিরে getLastNonConfigurationInstance সময় onCreate এবং এটি পুনরায় বরাদ্দ।

এখনও কাজ করে না বলে মনে হচ্ছে। আমি সাহায্য করতে পারি না তবে ভাবছি আমি যদিও সত্যিই কাছে আছি! এখনও অবধি, আমি কেবল একটি ফাঁকা / সাদা-পটভূমি ওয়েবভিউ পেয়েছি তার পরিবর্তে । আশা করি এখানে পোস্ট করা যে কেউ এটিকে শেষের লাইনের পাশ কাটাতে সহায়তা করতে পারে।

হয়তো আমার ওয়েবভিউটি পাস করা উচিত নয় । ওয়েবভিউয়ের মধ্যে থেকে সম্ভবত কোনও জিনিস ?

আমি চেষ্টা না করে অন্য পদ্ধতিটি - আমার প্রিয় নয় - এটি কার্যকলাপে সেট করা হয়:

 android:configChanges="keyboardHidden|orientation"

... এবং তারপরে এখানে বেশ কিছু করবেন না:

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  // We do nothing here. We're only handling this to keep orientation
  // or keyboard hiding from causing the WebView activity to restart.
}

এটি কাজ করে তবে এটি সেরা অভ্যাস হিসাবে বিবেচিত হবে না

এদিকে, আমার কাছে একটি একক ইমেজভিউ রয়েছে যা আমি ঘোরাটির উপর নির্ভর করে স্বয়ংক্রিয়ভাবে আপডেট করতে চাই। এটি খুব সহজ হতে দেখা যাচ্ছে। আমার resফোল্ডারের অধীনে , আমি ল্যান্ডস্কেপ / প্রতিকৃতি বৈচিত্রগুলি ধরে রেখেছি drawable-landএবং drawable-portতারপরে আমি চিত্রকল্পেরR.drawable.myimagename জন্য ব্যবহার করি use Yay - এর উৎস এবং Android এ "ডান জিনিস আছে"!

... আপনি যখন কনফিগারেশনের পরিবর্তনের জন্য নজর রাখবেন তা বাদ দিলে তা হয় না। :(

সুতরাং আমি মতবিরোধ করছি। ব্যবহারের onRetainNonConfigurationInstance এবং ImageView ঘূর্ণন কাজ, কিন্তু ওয়েবদৃশ্য অধ্যবসায় না ... বা ব্যবহারের onConfigurationChanged এবং ওয়েবদৃশ্য থাকার বিষয়টি মতেই স্থিতিশীল, কিন্তু ImageView আপডেট নেই। কি করো?

একটি সর্বশেষ নোট: আমার ক্ষেত্রে, জোর দেওয়া ওরিয়েন্টেশন কোনও গ্রহণযোগ্য আপস নয়। আমরা সত্যিই করুণভাবে ঘূর্ণন সমর্থন করতে চান না। কিন্ডার মতো অ্যান্ড্রয়েড ব্রাউজার অ্যাপটি কী করে! ;)


7
আর রিটেনন কনফিগারেশনআইনস্ট্যান্স থেকে আপনার কোনও দর্শন ফিরিয়ে দেওয়া উচিত নয়। ক্রিয়াকলাপের প্রসঙ্গে ভিউগুলি সংযুক্ত থাকে তাই আপনি যদি প্রতি বার দৃষ্টিভঙ্গি পরিবর্তন হয় তবে আপনি সেই সমস্ত ব্যাগেজটি বহন করে এমন দৃশ্যটি সংরক্ষণ করেন। ভিউটি "ফাঁস" হয়েছে। (এখানে সর্বশেষ অনুচ্ছেদ দেখুন: ডেভেলপার.অ্যান্ড্রয়েড / রিসোর্স / আর্টিকেলস /)) #RetainNonConfigrationInstance এর জন্য সেরা অনুশীলন হ'ল ভিউটি নয়, ভিউর প্রয়োজন অনুযায়ী ডেটা সংরক্ষণ করা।
ডান্লান শানাগি

3

একটি আপস হ'ল ঘূর্ণন এড়ানো। কেবল প্রতিকৃতি নির্দেশের জন্য ক্রিয়াকলাপ ঠিক করতে এটি যুক্ত করুন।

android:screenOrientation="portrait"

এটি আসলে অনেক ক্ষেত্রে কাজ করে এবং সমাধানটি আমি বাস্তবায়নের সিদ্ধান্ত নিয়েছি :-)
আবদো

1
ওহে, এটি একটি প্রয়োজনীয় পরিবর্তন
ম্যাক্স Ch

3

ওরিয়েন্টেশন পরিবর্তনগুলি পরিচালনা করার এবং রোটেটে ওয়েবভিউ পুনরায় লোড প্রতিরোধের সেরা উপায়।

@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}

এই বিষয়টি মাথায় রেখে, প্রতিবার আপনি অভিমুখ পরিবর্তন করার সময় অনক্রিট () কল করা থেকে রোধ করতে আপনাকে যুক্ত করতে হবে android:configChanges="orientation|screenSize" to the AndroidManifest.

বা শুধু ..

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"`

3

আপনার ম্যানিফেস্ট ফাইলে কেবল নিম্নলিখিত কোড লাইনগুলি লিখুন - আর কিছুই নয়। এটা সত্যিই কাজ করেছে:

<activity android:name=".YourActivity"
  android:configChanges="orientation|screenSize"
  android:label="@string/application_name">

3

আমি প্রশংসা করি যে এটি একটু দেরিতে হয়েছে, তবে এটি আমার উত্তরটি বিকাশের সময় আমি যে উত্তরটি ব্যবহার করেছি:

Andro আইডি

    <activity
        android:name=".WebClient"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize" <--- "screenSize" important
        android:label="@string/title_activity_web_client" >
    </activity>

WebClient.java

public class WebClient extends Activity {

    protected FrameLayout webViewPlaceholder;
    protected WebView webView;

    private String WEBCLIENT_URL;
    private String WEBCLIENT_TITLE;

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

    @SuppressLint("SetJavaScriptEnabled")
    protected void initUI(){
        // Retrieve UI elements
        webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder));

        // Initialize the WebView if necessary
        if (webView == null)
        {
            // Create the webview
            webView = new WebView(this);
            webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setBuiltInZoomControls(true);
            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
            webView.setScrollbarFadingEnabled(true);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setPluginState(android.webkit.WebSettings.PluginState.ON);
            webView.getSettings().setLoadsImagesAutomatically(true);

            // Load the URLs inside the WebView, not in the external web browser
            webView.setWebViewClient(new SetWebClient());
            webView.setWebChromeClient(new WebChromeClient());

            // Load a page
            webView.loadUrl(WEBCLIENT_URL);
        }

        // Attach the WebView to its placeholder
        webViewPlaceholder.addView(webView);
    }

    private class SetWebClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }else if(id == android.R.id.home){
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
            return;
        }

        // Otherwise defer to system default behavior.
        super.onBackPressed();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        if (webView != null){
            // Remove the WebView from the old placeholder
            webViewPlaceholder.removeView(webView);
        }

        super.onConfigurationChanged(newConfig);

        // Load the layout resource for the new configuration
        setContentView(R.layout.activity_web_client);

        // Reinitialize the UI
        initUI();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);

        // Save the state of the WebView
        webView.saveState(outState);
    }

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

        // Restore the state of the WebView
        webView.restoreState(savedInstanceState);
    }

}

2

ব্যবহার করে আপনি চেষ্টা করে দেখতে পারেন onSaveInstanceState()এবং onRestoreInstanceState()আপনার কার্যকলাপ ডাকতে উপর saveState(...)এবং restoreState(...)আপনার ওয়েব দর্শন দৃষ্টান্ত হবে।


2

এটি 2015, এবং অনেক লোক একটি সমাধান খুঁজছেন যা এখনও জেলিবিয়ান, কে এবং ললিপপ ফোনে কাজ করে। অনেক লড়াইয়ের পরে আমি ওরিয়েন্টেশন পরিবর্তন করার পরেও ওয়েভভিউ অক্ষত রাখার একটি উপায় পেয়েছি। আমার কৌশলটি মূলত ওয়েবভিউকে অন্য শ্রেণিতে পৃথক স্ট্যাটিক ভেরিয়েবলে সঞ্চয় করা। তারপরে, যদি ঘূর্ণন ঘটে, তবে আমি ওয়েবভিউটিকে ক্রিয়াকলাপ থেকে বিচ্ছিন্ন করি, ওরিয়েন্টেশনটি শেষ হওয়ার অপেক্ষায় থাকি এবং ওয়েবভিউটিকে আবার কার্যকলাপে ফিরিয়ে আনি। উদাহরণস্বরূপ ... প্রথমে এটি আপনার ম্যানিফেষ্টে রাখুন (কীবোর্ডহাইড এবং কীবোর্ড alচ্ছিক)

<application
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="com.myapp.abc.app">

    <activity
            android:name=".myRotatingActivity"
            android:configChanges="keyboard|keyboardHidden|orientation">
    </activity>

একটি পৃথক আবেদন শ্রেণিতে, রাখুন:

     public class app extends Application {
            public static WebView webview;
            public static FrameLayout webviewPlaceholder;//will hold the webview

         @Override
               public void onCreate() {
                   super.onCreate();
    //dont forget to put this on the manifest in order for this onCreate method to fire when the app starts: android:name="com.myapp.abc.app"
                   setFirstLaunch("true");
           }

       public static String isFirstLaunch(Context appContext, String s) {
           try {
          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
          return prefs.getString("booting", "false");
          }catch (Exception e) {
             return "false";
          }
        }

    public static void setFirstLaunch(Context aContext,String s) {
       SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(aContext);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("booting", s);
            editor.commit();
           }
        }

ক্রিয়াকলাপে লিখেছেন:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(app.isFirstLaunch.equals("true"))) {
            app.setFirstLaunch("false");
            app.webview = new WebView(thisActivity);
            initWebUI("www.mypage.url");
        }
}
@Override
    public  void onRestoreInstanceState(Bundle savedInstanceState) {
        restoreWebview();
    }

public void restoreWebview(){
        app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
        if(app.webviewPlaceholder.getParent()!=null&&((ViewGroup)app.webview.getParent())!=null) {
            ((ViewGroup) app.webview.getParent()).removeView(app.webview);
        }
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
        app.webview.setLayoutParams(params);
        app.webviewPlaceholder.addView(app.webview);
        app.needToRestoreWebview=false;
    }

protected static void initWebUI(String url){
        if(app.webviewPlaceholder==null);
          app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
        app.webview.getSettings().setJavaScriptEnabled(true);       app.webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        app.webview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
        app.webview.getSettings().setSupportZoom(false);
        app.webview.getSettings().setBuiltInZoomControls(true);
        app.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        app.webview.setScrollbarFadingEnabled(true);
        app.webview.getSettings().setLoadsImagesAutomatically(true);
        app.webview.loadUrl(url);
        app.webview.setWebViewClient(new WebViewClient());
        if((app.webview.getParent()!=null)){//&&(app.getBooting(thisActivity).equals("true"))) {
            ((ViewGroup) app.webview.getParent()).removeView(app.webview);
        }
        app.webviewPlaceholder.addView(app.webview);
    }

অবশেষে, সহজ এক্সএমএল:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".myRotatingActivity">
    <FrameLayout
        android:id="@+id/webviewplaceholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

আমার সমাধানে বেশ কয়েকটি জিনিস উন্নত করা যেতে পারে, তবে আমি ইতিমধ্যে অনেকটা সময় ব্যয় করেছি, উদাহরণস্বরূপ: SharedPreferences স্টোরেজটি ব্যবহার না করে ক্রিয়াকলাপটি প্রথমবারের জন্য চালু করা হলে যাচাই করার একটি ছোট উপায়। এই পদ্ধতির সাহায্যে আপনি ওয়েবউভিউ অক্ষত (আফাইক), এর পাঠ্যবক্স, লেবেল, ইউআই, জাভাস্ক্রিপ্ট ভেরিয়েবল এবং নেভিগেশন স্টেটগুলি সংরক্ষণ করে যা ইউআরএল দ্বারা প্রতিবিম্বিত হয় না।


1
এমনকি আপনি যখন কনফিগারেশন পরিবর্তনগুলি ম্যানুয়ালি পরিচালনা করেন তখন ওয়েবভিউটি কখনই প্রথম স্থানে ধ্বংস হয় না, এমনকি কেন বিচ্ছিন্ন হওয়া এবং পুনরায় যোগাযোগ করা বিরক্ত করে?
ফ্রেড

@ ফ্রেড, কারণ আমি ওয়েবভিউ এবং তার বিষয়বস্তুর যথাযথ অবস্থা অক্ষুণ্ন রাখতে চাইছি, কুকিজ সহ এবং ওয়েবভিউ দ্বারা লোড হওয়া ওয়েবপৃষ্ঠায় এইচটিএমএল 5 বা জেএস দিয়ে প্রয়োগ করা বোতাম এবং চেকবক্সগুলির অবস্থা। আমি একমাত্র সমন্বয়টি হ'ল পুনরায় আকার দেওয়া।
জোশ

ফ্রেডের অর্থ হল আপনি ম্যানিফেস্টে কনফিগারচেন্জগুলি ঘোষণা করার সাথে সাথে আপনাকে স্ট্যাটিক ক্লাসের মাধ্যমে ওয়েবভিউকে আলাদা / পুনরায় সংযুক্ত করার দরকার নেই। এইভাবে, আপনার দর্শন এবং ক্রিয়াকলাপ কোনও অবস্থাতেই ঘোরার সময় নষ্ট হবে না।
ইউজিন কার্তোয়িয়েভ

2

আপনার কেবলমাত্র যা করা উচিত তা হ'ল এই কোডটি আপনার ম্যানিফেস্ট ফাইলটিতে যুক্ত করা:

<activity android:name=".YourActivity"
      android:configChanges="orientation|screenSize"
      android:label="@string/application_name">

2

আপডেট: বর্তমান কৌশল হ'ল ওয়েবভিউ উদাহরণটি অ্যাপ্লিকেশন শ্রেণিতে স্থানান্তরিত করার পরিবর্তে বর্ধিত খণ্ডের পরিবর্তে পুনরায় চালু করতে হবে এবং জোশের মতো পুনরায় শুরু করতে হবে। অ্যাপ্লিকেশনটি বন্ধ হতে বাধা দেওয়ার জন্য, ব্যবহারকারী যখন অ্যাপ্লিকেশনগুলির মধ্যে স্যুইচ করে আপনি স্থিতি বজায় রাখতে চান তবে আপনার অগ্রভাগ পরিষেবাটি ব্যবহার করা উচিত।

আপনি যদি টুকরোগুলি ব্যবহার করে থাকেন তবে আপনি ওয়েবউউয়ের রক্ষণাবেক্ষণ উদাহরণটি ব্যবহার করতে পারেন। ওয়েব ভিউ ক্লাসের উদাহরণ সদস্য হিসাবে ধরে রাখা হবে। যাইহোক আপনার পিতামাতার ধারক দিয়ে ধ্বংস থেকে রোধ করতে অনক্রেইটভিউতে ওয়েব ভিউ সংযুক্ত করে অনডেস্ট্রয়ভিউয়ের আগে আলাদা করা উচিত।

class MyFragment extends Fragment{  

    public MyFragment(){  setRetainInstance(true); }

    private WebView webView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       View v = ....
       LinearLayout ll = (LinearLayout)v.findViewById(...);
       if (webView == null) {
            webView = new WebView(getActivity().getApplicationContext()); 
       }
       ll.removeAllViews();
       ll.addView(webView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

       return v;
    }

    @Override
    public void onDestroyView() {
        if (getRetainInstance() && webView.getParent() instanceof ViewGroup) {
           ((ViewGroup) webView.getParent()).removeView(webView);
        }
        super.onDestroyView();
    } 
}

পিএস ক্রেডিটগুলি কেকপপকের উত্তরে যায়

'সেভস্টেট ()' হিসাবে এটি আর অফিসিয়াল ডকুমেন্টেশন অনুযায়ী কাজ করে না :

দয়া করে নোট করুন যে এই পদ্ধতিটি আর এই ওয়েবভিউর জন্য প্রদর্শন ডেটা সঞ্চয় করে না। পুনরুদ্ধার স্টেট (বান্ডিল) কখনও কল না করা হলে পূর্ববর্তী আচরণটি সম্ভাব্যভাবে ফাইলগুলি ফাঁস করতে পারে।


মনে রাখবেন যে setRetainInstanceখণ্ডটি ধরে রাখার সময় দৃশ্যটি (এবং সেইজন্য ওয়েবভিউ) এখনও ধ্বংস হয়ে যায়।
ফ্রেড

1
@ ফ্রেড আপনি কি এই বিবৃতিটির জন্য কোনও উত্স সরবরাহ করতে পারেন? আমি এটি একটি ছোট অ্যাপ্লিকেশনটিতে পরীক্ষা করেছি যাতে সেটরেটেইন ইনস্ট্যান্স (সত্য) দিয়ে একটি টুকরা রয়েছে যা একটি ইউটিউব পৃষ্ঠা প্রদর্শন করে এবং যদি আমি অভিমুখ পরিবর্তন করি তবে ভিডিওটি বাধাগ্রস্ত না হওয়ায় দৃশ্যটি ধরে রাখা হয়েছে বলে মনে হচ্ছে। ওয়েব ভিউটি ধ্বংস হচ্ছে বলে মনে হচ্ছে না।
পিঙ্কার্টন

@ রাই এটি কেবল একটি ভুল পড়া ছিল, এর পর থেকে আমি কিছুটা উত্তর সম্পাদনা করেছি (এটি এখনও কিছু শব্দ সংশোধন দরকার)। আপনি যদি বর্তমান অবস্থার বিষয়ে আগ্রহী হন - এই পদ্ধতিটি কাজ করে। তবে সমস্যাটি হ'ল অ্যান্ড্রয়েড মেমরি কম থাকলে অ্যাপ্লিকেশনটিকে হত্যা করে kill আমার একটি গুরুত্বপূর্ণ ইনপুট ফর্ম রয়েছে যেখানে ব্যবহারকারীকে অন্য অ্যাপ্লিকেশনটিতে একটি বার্তা পড়তে হবে, সুতরাং প্রক্রিয়াটি মারা যাওয়ার হাত থেকে রক্ষা পেতে আমাকে বিজ্ঞপ্তি সহ অগ্রণী পরিষেবা ব্যবহার করতে হয়েছিল। তবুও অ্যান্ড্রয়েড এখনও ক্রিয়াকলাপ ধ্বংস করে এবং তাই বজায় রাখা ফ্রেম। তবে অ্যাপ্লিকেশন ক্লাসের উদাহরণটি সংরক্ষিত আছে - তাই আমি এখন ওয়েবভিউকে অ্যাপ্লিকেশনে নিয়ে যাই।
বরিস ট্রুখভ

1
আমি ওয়েবউউয়ের ভিত্তি হিসাবে মিউটেবল কনটেক্সটওয়্যার্পার ব্যবহার করি, আমি সংযুক্তি এবং বিচ্ছিন্নকরণের ক্রিয়াকলাপগুলিতে প্রসঙ্গটি স্যুইচ করি। ক্রোমিয়াম জুম নিয়ন্ত্রণে তৈরি করে এমন আরও একটি বড় সমস্যা পুরানো ক্রিয়াকলাপের রেফারেন্স সংরক্ষণ করে, তাই ক্রিয়াকলাপের পরিবর্তে অ্যাপ্লিকেশনের সাথে ওয়েব ভিউয়ের সাথে সংযুক্ত কোনও জুম সমাধান হয় না। টি এল; ডিআর; যদি আপনার ফর্মটি তাত্পর্যপূর্ণ না হয় এবং আপনি সত্যের সাথে বাঁচতে পারেন যে অ্যাপ্লিকেশন স্যুইচ করার পরে আপনার প্রক্রিয়াটি মেরে ফেলা যায় এবং ওয়েবভিউ পুনরুদ্ধার করা যায় না ধরে রাখা ফ্রেম সমাধান সহ যান। পিএস এছাড়াও আমি মনে করি যে গুগল কর্মীরা তাদের সমস্ত উইজেট-গ্যাজেটগুলির সাথে বাস্তব জীবনের সমস্যাগুলি থেকে অনেক দূরে ...
বরিস ট্রুখভ

1
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}

এই পদ্ধতিগুলি যে কোনও ক্রিয়াকলাপে ওভাররাইড করা যায়, মূলত আপনি যখনই কোনও ক্রিয়াকলাপ তৈরি করা / ধ্বংস করা হয় তখন মূলত আপনাকে মানগুলি সংরক্ষণ এবং পুনরুদ্ধার করতে দেয়, যখন স্ক্রিনের ওরিয়েন্টেশন পরিবর্তনটি ব্যাকগ্রাউন্ডে ধ্বংস হয়ে যায় এবং পুনরায় তৈরি করা হয়, সুতরাং আপনি এই পদ্ধতিগুলি ব্যবহার করতে পারেন পরিবর্তনের সময় অস্থায়ী স্টোর / পুনরুদ্ধার রাজ্যে।

নিম্নলিখিত দুটি পদ্ধতিতে আপনার আরও গভীর নজর দেওয়া উচিত এবং এটি আপনার সমাধানের সাথে খাপ খায় কিনা তা দেখুন।

http://developer.android.com/reference/android/app/Activity.html


1

সবচেয়ে ভালো সমাধান পূর্ববর্তী লিক ছাড়া আমি এই কাজ করতে পাওয়া যায় Activityরেফারেন্স এবং সেটিং ছাড়া configChanges.. একটি ব্যবহার করা MutableContextWrapper

আমি এটি এখানে প্রয়োগ করেছি: https://github.com/slightfoot/android-web-wrapper/blob/48cb3c48c457d889fc16b4e3eba1c9e925f42cfb/WebWrapper/src/com/example/webwrapper/BrowserActivity.java


এই পার্শ্ব প্রতিক্রিয়া ছাড়া নির্ভরযোগ্যভাবে কাজ করে? এই পদ্ধতি সম্পর্কে আমি খুব বেশি তথ্য পাই না।
ক্রেগারস 84

1

এটিই আমার পক্ষে কাজ করেছে (আমি এমনকি সেভ ইনস্ট্যান্সের স্টেটটি ব্যবহার করেছি onCreateViewতবে এটি নির্ভরযোগ্য ছিল না)।

public class WebViewFragment extends Fragment
{
    private enum WebViewStateHolder
    {
        INSTANCE;

        private Bundle bundle;

        public void saveWebViewState(WebView webView)
        {
            bundle = new Bundle();
            webView.saveState(bundle);
        }

        public Bundle getBundle()
        {
            return bundle;
        }
    }

    @Override
    public void onPause()
    {
        WebViewStateHolder.INSTANCE.saveWebViewState(myWebView);
        super.onPause();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
        ButterKnife.inject(this, rootView);
        if(WebViewStateHolder.INSTANCE.getBundle() == null)
        {
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader br = null;
            try
            {
                br = new BufferedReader(new InputStreamReader(getActivity().getAssets().open("start.html")));

                String line = null;
                while((line = br.readLine()) != null)
                {
                    stringBuilder.append(line);
                }
            }
            catch(IOException e)
            {
                Log.d(getClass().getName(), "Failed reading HTML.", e);
            }
            finally
            {
                if(br != null)
                {
                    try
                    {
                        br.close();
                    }
                    catch(IOException e)
                    {
                        Log.d(getClass().getName(), "Kappa", e);
                    }
                }
            }
            myWebView
                .loadDataWithBaseURL("file:///android_asset/", stringBuilder.toString(), "text/html", "utf-8", null);
        }
        else
        {
            myWebView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
        }
        return rootView;
    }
}

আমি ওয়েব ভিউয়ের রাজ্যের জন্য একটি সিঙ্গলটন ধারক তৈরি করেছি। যতক্ষণ না আবেদনের প্রক্রিয়াটি বিদ্যমান থাকবে রাষ্ট্র ততক্ষণ সংরক্ষণ করা হবে।

সম্পাদনা: loadDataWithBaseURLএটি প্রয়োজনীয় ছিল না, এটি ঠিক পাশাপাশি কাজ করেছে

    //in onCreate() for Activity, or in onCreateView() for Fragment

    if(WebViewStateHolder.INSTANCE.getBundle() == null) {
        webView.loadUrl("file:///android_asset/html/merged.html");
    } else {
        webView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
    }

যদিও আমি এটি পড়ি অগত্যা কুকিগুলির সাথে ভালভাবে কাজ করে না।


সিঙ্গেলটন ব্যবহার করা সমস্যাযুক্ত কারণ এটি ধরে নেওয়া হয় যে আপনার কেবলমাত্র একটি উদাহরণ ব্যবহার করতে হবে।
অ্যান্ড্রয়েড বিকাশকারী

নিবন্ধন করুন ঠিক আছে, যদি এটি আপনার ক্ষেত্রে সত্য না হয়, তবে প্রকৃতপক্ষে এটিই একটি সমস্যা। আমার কাছে কেবলমাত্র একটি ওয়েবভিউ উদাহরণ ছিল, সুতরাং এই প্রশ্নটি আমার কাছে আসেনি।
এপিকপান্ডাফোরস

1

এটা চেষ্টা কর

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView wv;

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

        wv = (WebView) findViewById(R.id.webView);
        String url = "https://www.google.ps/";

        if (savedInstanceState != null)
            wv.restoreState(savedInstanceState);
        else {
            wv.setWebViewClient(new MyBrowser());
            wv.getSettings().setLoadsImagesAutomatically(true);
            wv.getSettings().setJavaScriptEnabled(true);
            wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            wv.loadUrl(url);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        wv.saveState(outState);
    }

    @Override
    public void onBackPressed() {
        if (wv.canGoBack())
            wv.goBack();
        else
            super.onBackPressed();
    }

    private class MyBrowser extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

}

0

এই পৃষ্ঠাটি আমার সমস্যার সমাধান করে তবে প্রাথমিক পর্যায়ে আমাকে সামান্য পরিবর্তন করতে হবে:

    protected void onSaveInstanceState(Bundle outState) {
       webView.saveState(outState);
       }

এই অংশটি আমার জন্য এটি একটি সামান্য সমস্যা আছে। দ্বিতীয় অভিযোজন পরিবর্তনে নাল পয়েন্টার দিয়ে অ্যাপ্লিকেশনটি সমাপ্ত হয়

এটি ব্যবহার করে এটি আমার পক্ষে কাজ করেছে:

    @Override
protected void onSaveInstanceState(Bundle outState ){
    ((WebView) findViewById(R.id.webview)).saveState(outState);
}

ঠিক একই রকম বলে মনে হচ্ছে দ্বিতীয়টি কেন কাজ করবে যখন আগেরটি হবে না?
অ্যান্ড্রয়েড বিকাশকারী

0

আপনার এটি চেষ্টা করা উচিত:

  1. সেই পরিষেবাটির ভিতরে একটি পরিষেবা তৈরি করুন, আপনার ওয়েবভিউ তৈরি করুন।
  2. আপনার ক্রিয়াকলাপ থেকে পরিষেবাটি শুরু করুন এবং এর সাথে আবদ্ধ হন।
  3. ইন onServiceConnectedপদ্ধতি, ওয়েব দর্শন পেতে এবং কল setContentViewআপনার ওয়েব দর্শন রেন্ডার করতে পদ্ধতি।

আমি এটি পরীক্ষা করেছি এবং এটি কাজ করে তবে এক্সওয়ালকভিউ বা গেকোভিউয়ের মতো অন্যান্য ওয়েবভিউগুলির সাথে নয়।


ওহে! আপনি আরও ব্যাখ্যা করতে পারেন? আপনাকে ধন্যবাদ
জ্যাকো

1
ঠিক আছে, আপনার ওয়েবভিউ উদাহরণটি আপনাকে ক্রিয়াকলাপ হিসাবে তৈরি করুন এবং পশ্চাদপটে চলছে এমন একটি পরিষেবার প্রতি তার পুনঃসংশোধন করার চেষ্টা করুন। পরের বার আপনি সেই ক্রিয়াকলাপটি খুললে প্রথমে সংরক্ষিত ওয়েবভিউটি পাওয়ার চেষ্টা করুন এবং এটি রেন্ডার করুন।
রামদান ওউলিটসেন

0
@Override
    protected void onSaveInstanceState(Bundle outState )
    {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onRestoreInstanceState(savedInstanceState);
        webView.restoreState(savedInstanceState);
    }

আপনি কি নিজের উত্তরে কিছু লাইন যুক্ত করতে পারবেন?
ইয়্যাক

-1

আমি এই সমাধানটি পছন্দ করি http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/

এটি অনুসারে আমরা ওয়েবউভের একই উদাহরণটি পুনরায় ব্যবহার করি। এটি নেভিগেশন ইতিহাস সংরক্ষণ করতে এবং কনফিগারেশন পরিবর্তনে স্ক্রোল অবস্থানের অনুমতি দেয়।


উপরের লিঙ্কটি এমন কোনও পৃষ্ঠায় নিয়ে যায় যা কিছু 'সুরক্ষা প্লাগইন' ইনস্টল না করে দেখা যায় না; এড়াতে.
অ্যালান বাজনেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.