首页 > 解决方案 > Android Back Stack 不会清除

问题描述

编辑:我想出了问题所在。我有 2 个意图(一个用于用户登录时,一个用于用户已经登录),我只更改了第一个从未实际运行的意图。我对此感到愚蠢,但我感谢每个试图提供帮助的人。

所以我有一个登录活动和一个主要活动,我希望从后台堆栈中删除登录活动,这样用户一旦登录就无法返回它。我知道这应该相当简单,我已经尝试了很多东西,但它仍然无法正常工作。我已经尝试过所有 3 个这样的“标志”:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

并一次添加一个。我也尝试过放置线条finish()finishAffinity()围绕意图线,但仍然没有运气。我究竟做错了什么?

这是与意图相关的代码:

Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);

编辑:请求的代码:

AndroidManifest.xml

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

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"/>
        <activity
            android:name=".RegisterActivity"
            android:label="" />
        <activity
            android:name=".LoginActivity"
            android:label="">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

登录活动.java

package com.example.music;

import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import android.app.ActivityOptions;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.RequestQueue;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.example.music.ui.Token;
import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;

public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        GlobalVariables globalVariables = new GlobalVariables();

        final TextView title = findViewById(R.id.title);
        final EditText email = findViewById(R.id.emailInput);
        final EditText password = findViewById(R.id.passwordInput);
        final Button signUp = findViewById(R.id.signUp);
        Button signIn = findViewById(R.id.signIn);

        //check if token exists
        SharedPreferences sharedPreferences = getSharedPreferences("StoredValues", MODE_PRIVATE);
        String token = sharedPreferences.getString("token", "null");
        if(!token.equals("null")){
            globalVariables.setToken(token);
            Intent myIntent = new Intent(LoginActivity.this, MainActivity.class);
            LoginActivity.this.startActivity(myIntent);
        }

        signUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent openRegisterActivity = new Intent(LoginActivity.this, RegisterActivity.class);

                Pair[] pairs = new Pair[4];
                pairs[0] = new Pair<View, String>(title, "titleTransition");
                pairs[1] = new Pair<View, String>(email, "emailTransition");
                pairs[2] = new Pair<View, String>(password, "passwordTransition");
                pairs[3] = new Pair<View, String>(signUp, "signUpTransition");

                ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(LoginActivity.this, pairs);
                getWindow().setExitTransition(null);
                startActivity(openRegisterActivity, options.toBundle());
            }
        });

        signIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {
                Utils utils = new Utils(getApplicationContext());
                GlobalVariables globalVariables = new GlobalVariables();
                if(email.getText().toString().equals("") || password.getText().toString().equals("")){
                    //at least one input is empty
                    utils.DisplayPopup(view, getResources().getString(R.string.empty_input_box));
                }
                else{
                    //everything is good to go
                    String url = globalVariables.getIPAddress() + "login/";

                    RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

                    try {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("username", email.getText().toString());
                        jsonObject.put("password", password.getText().toString());

                        JsonObjectRequest objectRequest = new JsonObjectRequest(
                                com.android.volley.Request.Method.POST,
                                url,
                                jsonObject,
                                new com.android.volley.Response.Listener<JSONObject>() {
                                    @Override
                                    public void onResponse(JSONObject response) {
                                        Gson gson = new Gson();
                                        Token token = gson.fromJson(response.toString(), Token.class);

                                        SharedPreferences sharedPreferences = getSharedPreferences("StoredValues", MODE_PRIVATE);
                                        SharedPreferences.Editor editor = sharedPreferences.edit();
                                        editor.putString("token", token.toString());
                                        editor.apply();

                                        Intent intent;
                                        intent = MainActivity.getIntentWithNewTask(getApplicationContext());
                                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                                        startActivity(intent);
                                        LoginActivity.this.finish();

                                        Log.e("REST Response", response.toString());
                                    }
                                },
                                new com.android.volley.Response.ErrorListener() {
                                    @Override
                                    public void onErrorResponse(VolleyError error) {
                                        Utils utils = new Utils(getApplicationContext());
                                        Log.e("REST Response", error.toString());
                                        if(error.networkResponse.statusCode == 400){
                                            utils.DisplayPopup(view, getResources().getString(R.string.invalid_credentials));
                                        }
                                    }
                                });
                        objectRequest.setRetryPolicy(new RetryPolicy() {
                            @Override
                            public int getCurrentTimeout() {
                                return 10000;
                            }

                            @Override
                            public int getCurrentRetryCount() {
                                return 10000;
                            }

                            @Override
                            public void retry(VolleyError error) throws VolleyError {
                                Log.e("Volley error", error.toString());
                            }
                        });

                        requestQueue.add(objectRequest);

                    } catch (JSONException e){
                        Log.e("JSON Response", e.toString());
                    }
                }
            }
        });
    }
}

MainActivity.java

package com.example.music;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;

import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;

import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import com.example.music.ui.main.SectionsPagerAdapter;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = findViewById(R.id.tabs);
        tabs.setupWithViewPager(viewPager);
        FloatingActionButton fab = findViewById(R.id.fab);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.logOut:
                SharedPreferences sharedPreferences = getSharedPreferences("StoredValues", MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putString("token", "null");
                editor.apply();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public static Intent getIntent(Context context) {
        return new Intent(context, MainActivity.class);
    }

    public static Intent getIntentWithNewTask(Context context) {
        if(context!=null)
        {

            Intent intent = getIntent(context);

            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            return intent;
        }
        return null;
    }

}

最小 SDK: 21 目标 SDK: 29

编辑2:

我现在通过覆盖onBackPressedMainActivity 中的方法以“回家”而不是“返回”来解决这个问题。如果有人有不同的建议,请告诉我。

标签: androidandroid-activityback-stack

解决方案


您的问题是您的活动没有在执行 UI 操作的主线程上开始。我添加了一个处理程序来执行此操作,下面是您更新的LoginActivity代码。

我创建了一个基本上Handler是在其中创建的(因为附加到创建它的线程)并且当您获得成功响应时,处理程序将收到通知并且我们将检查活动是否处于活动状态(以避免泄漏因为用户可以杀死该应用程序并且您的响应随后出现)。onCreateMain ThreadHandlerHandler

public class LoginActivity extends AppCompatActivity {

    private Handler startMainActivityHandler;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        GlobalVariables globalVariables = new GlobalVariables();
        startMainActivityHandler = new StartActivityHandler(this);

        final TextView title = findViewById(R.id.title);
        final EditText email = findViewById(R.id.emailInput);
        final EditText password = findViewById(R.id.passwordInput);
        final Button signUp = findViewById(R.id.signUp);
        Button signIn = findViewById(R.id.signIn);

        //check if token exists
        SharedPreferences sharedPreferences = getSharedPreferences("StoredValues", MODE_PRIVATE);
        String token = sharedPreferences.getString("token", "null");
        if(!token.equals("null")){
            globalVariables.setToken(token);
            Intent myIntent = new Intent(LoginActivity.this, MainActivity.class);
            LoginActivity.this.startActivity(myIntent);
        }

        signUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent openRegisterActivity = new Intent(LoginActivity.this, RegisterActivity.class);

                Pair[] pairs = new Pair[4];
                pairs[0] = new Pair<View, String>(title, "titleTransition");
                pairs[1] = new Pair<View, String>(email, "emailTransition");
                pairs[2] = new Pair<View, String>(password, "passwordTransition");
                pairs[3] = new Pair<View, String>(signUp, "signUpTransition");

                ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(LoginActivity.this, pairs);
                getWindow().setExitTransition(null);
                startActivity(openRegisterActivity, options.toBundle());
            }
        });

        signIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {
                Utils utils = new Utils(getApplicationContext());
                GlobalVariables globalVariables = new GlobalVariables();
                if(email.getText().toString().equals("") || password.getText().toString().equals("")){
                    //at least one input is empty
                    utils.DisplayPopup(view, getResources().getString(R.string.empty_input_box));
                }
                else{
                    //everything is good to go
                    String url = globalVariables.getIPAddress() + "login/";

                    RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

                    try {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("username", email.getText().toString());
                        jsonObject.put("password", password.getText().toString());

                        JsonObjectRequest objectRequest = new JsonObjectRequest(
                                com.android.volley.Request.Method.POST,
                                url,
                                jsonObject,
                                new com.android.volley.Response.Listener<JSONObject>() {
                                    @Override
                                    public void onResponse(JSONObject response) {
                                        Gson gson = new Gson();
                                        Token token = gson.fromJson(response.toString(), Token.class);

                                        SharedPreferences sharedPreferences = getSharedPreferences("StoredValues", MODE_PRIVATE);
                                        SharedPreferences.Editor editor = sharedPreferences.edit();
                                        editor.putString("token", token.toString());
                                        editor.apply();


                                        Log.e("REST Response", response.toString());
                                        startMainActivityHandler.sendEmptyMessage(1);
                                    }
                                },
                                new com.android.volley.Response.ErrorListener() {
                                    @Override
                                    public void onErrorResponse(VolleyError error) {
                                        Utils utils = new Utils(getApplicationContext());
                                        Log.e("REST Response", error.toString());
                                        if(error.networkResponse.statusCode == 400){
                                            utils.DisplayPopup(view, getResources().getString(R.string.invalid_credentials));
                                        }
                                    }
                                });
                        objectRequest.setRetryPolicy(new RetryPolicy() {
                            @Override
                            public int getCurrentTimeout() {
                                return 10000;
                            }

                            @Override
                            public int getCurrentRetryCount() {
                                return 10000;
                            }

                            @Override
                            public void retry(VolleyError error) throws VolleyError {
                                Log.e("Volley error", error.toString());
                            }
                        });

                        requestQueue.add(objectRequest);

                    } catch (JSONException e){
                        Log.e("JSON Response", e.toString());
                    }
                }
            }
        });
    }

    private static class StartActivityHandler extends Handler {

        private final WeakReference<Activity> weakReference;

        StartActivityHandler(Activity activity) {
            weakReference = new WeakReference<Activity>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == 1 && weakReference.get() != null && !weakReference.get().isDestroyed()) {
                Intent intent;
                intent = MainActivity.getIntentWithNewTask(getApplicationContext());
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                weakReference.get().startActivity(intent);
                weakReference.get().finish();

            }
        }
    }
}

推荐阅读