Toast消息崩溃应用

时间:2015-02-01 12:45:12

标签: java android android-activity toast

我试图在onCreate之外创建一个toast消息。 这是我的剧本:

package com.klh.lehava;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Locale;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings.Global;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends Activity {
    static MainActivity MenuChecker = new MainActivity();
    private static String response_str;
    private static HttpResponse result;
    private DrawerLayout mDrawerLayout;
    private static ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    private ArrayAdapter<String> adapter1;

    private static String isUserLoggedIn;

    public String isUserLoggedIn() {
        return isUserLoggedIn;
    }

    private static String getUrl;

    public String getUrl() {
        return getUrl;
    }

    public static final String TAG = "loginCookie";

    private CharSequence mDrawerTitle;
    private static CharSequence mTitle;

    //private final ArrayList<String> assignArr0 = new ArrayList<String>();
    private static String[] mPlanetTitles;
    private String[] newAr;



    @Override
    protected void onCreate(Bundle savedInstanceState) {

        WebView webview;
        webview = (WebView) findViewById(R.id.webview);


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);



        // set a custom shadow that overlays the main content when the drawer opens
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        // set up the drawer's list view with items and click listener
        adapter1 = new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mPlanetTitles);
        mDrawerList.setAdapter(adapter1);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        // enable ActionBar app icon to behave as action to toggle nav drawer
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);


        // ActionBarDrawerToggle ties together the the proper interactions
        // between the sliding drawer and the action bar app icon
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
                ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            selectItem(0);
        }
    }

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

    /* Called whenever we call invalidateOptionsMenu() */
    /*@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }*/

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
         // The action bar home/up action should open or close the drawer.
         // ActionBarDrawerToggle will take care of this.
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle action buttons
        switch(item.getItemId()) {
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    /* The click listner for ListView in the navigation drawer */
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {
        // update the main content by replacing fragments
        Bundle args = new Bundle();

        if (position == 0)
        {
            Fragment fragment = new MainFragment();
            args.putInt(MainFragment.ARG_PLANET_NUMBER, position);

            fragment.setArguments(args);

            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
        if (position == 1)
        {
            Fragment fragment = new InOutFragment();
            args.putInt(InOutFragment.ARG_PLANET_NUMBER, position);

            fragment.setArguments(args);

            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
        if (position == 2)
        {
            Fragment fragment = new AddEventFragment();
            args.putInt(AddEventFragment.ARG_PLANET_NUMBER, position);

            fragment.setArguments(args);

            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
        if (position == 3)
        {
            Fragment fragment = new AboutFragment();
            args.putInt(AboutFragment.ARG_PLANET_NUMBER, position);

            fragment.setArguments(args);

            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);



        }
        if (position == 4)
        {
            Fragment fragment = new WebLogoutFragment();
            args.putInt(WebLogoutFragment.ARG_PLANET_NUMBER, position);

            fragment.setArguments(args);

            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(0, true);
            setTitle(mPlanetTitles[0]);
            mDrawerLayout.closeDrawer(mDrawerList);

        }

        //isLoggedIn=IsLoggedIn();





        // update selected item and title, then close the drawer

    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    /**
     * When using the ActionBarDrawerToggle, you must call it during
     * onPostCreate() and onConfigurationChanged()...
     */

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /**
     * Fragment that appears in the "content_frame", shows a planet
     */
    public static class PlanetFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";


        public PlanetFragment() {
            // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {


            /*TextView textView = (TextView)getActivity(). findViewById(R.id.textView1);
            textView.setText("hi");*/


            //Toast.makeText(context, positions, duration).show();

                View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
                int i = getArguments().getInt(ARG_PLANET_NUMBER);
                String planet = getResources().getStringArray(R.array.planets_array)[i];

                int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
                                "drawable", getActivity().getPackageName());
                ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
                getActivity().setTitle(planet);
            return rootView;
        }
    }

    public static class AboutFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";


        public AboutFragment() {
                // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        {     
            View rootView = inflater.inflate(R.layout.fragment_about, container, false);
            int i = getArguments().getInt(ARG_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];


            /*int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
                          "drawable", getActivity().getPackageName());
           ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);*/
            getActivity().setTitle(planet);

            return rootView;
        }
    }
    public static class MainFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";

        public static final String MY_DOMAIN = "klh-dev.com";

        public MainFragment() {
                // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        {     

            View rootView = inflater.inflate(R.layout.fragment_web, container, false);
            int i = getArguments().getInt(ARG_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];



            WebView webview;
            webview = (WebView) rootView.findViewById(R.id.webview);

            webview.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    String weburl = view.getUrl();
                    String cookies = CookieManager.getInstance().getCookie(url);
                    getUrl = view.getUrl();
                    isUserLoggedIn=IsLoggedIn();
                    Log.d(TAG, "All the cookies in a string:" + cookies);
                    if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php")) {
                        mDrawerList.setItemChecked(0, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mtimecounter.php")) {
                        mDrawerList.setItemChecked(1, true);
                        getActivity().getActionBar().setTitle("כניסה/יציאה");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/madd.php")) {
                        mDrawerList.setItemChecked(2, true);
                        getActivity().getActionBar().setTitle("הוספת אירוע");
                    }
                }
            });
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setUseWideViewPort(true);
            webview.setWebChromeClient(new WebChromeClient());
            webview.loadUrl("http://www.klh-dev.com/lehava/lehava/system/mlogin.php");



            getActivity().setTitle(planet);

            return rootView;
        }
    }
    public static class InOutFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";

        public static final String MY_DOMAIN = "klh-dev.com";

        public InOutFragment() {
                // Empty constructor required for fragment subclasses
        }



        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        {     

            View rootView = inflater.inflate(R.layout.fragment_web, container, false);
            int i = getArguments().getInt(ARG_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];



            WebView webview;
            webview = (WebView) rootView.findViewById(R.id.webview);

            webview.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    String weburl = view.getUrl();
                    String cookies = CookieManager.getInstance().getCookie(url);
                    getUrl = view.getUrl();
                    isUserLoggedIn=IsLoggedIn();
                    Log.d(TAG, "All the cookies in a string:" + cookies);
                    if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php")) {
                        mDrawerList.setItemChecked(0, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mtimecounter.php")) {
                        mDrawerList.setItemChecked(1, true);
                        getActivity().getActionBar().setTitle("כניסה/יציאה");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/madd.php")) {
                        mDrawerList.setItemChecked(2, true);
                        getActivity().getActionBar().setTitle("הוספת אירוע");
                    }
                }
            });
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setUseWideViewPort(true);
            webview.setWebChromeClient(new WebChromeClient());
            webview.loadUrl("http://www.klh-dev.com/lehava/lehava/system/mtimecounter.php");



            getActivity().setTitle(planet);

            return rootView;
        }
    }
    public static class AddEventFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";

        public static final String MY_DOMAIN = "klh-dev.com";

        public AddEventFragment() {
                // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        {     

            View rootView = inflater.inflate(R.layout.fragment_web, container, false);
            int i = getArguments().getInt(ARG_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];



            WebView webview;
            webview = (WebView) rootView.findViewById(R.id.webview);

            webview.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    String weburl = view.getUrl();
                    String cookies = CookieManager.getInstance().getCookie(url);
                    getUrl = view.getUrl();
                    isUserLoggedIn=IsLoggedIn();
                    Log.d(TAG, "All the cookies in a string:" + cookies);
                    if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php")) {
                        mDrawerList.setItemChecked(0, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mtimecounter.php")) {
                        mDrawerList.setItemChecked(1, true);
                        getActivity().getActionBar().setTitle("כניסה/יציאה");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/madd.php")) {
                        mDrawerList.setItemChecked(2, true);
                        getActivity().getActionBar().setTitle("הוספת אירוע");
                    }
                }
            });
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setUseWideViewPort(true);
            webview.setWebChromeClient(new WebChromeClient());
            webview.loadUrl("http://www.klh-dev.com/lehava/lehava/system/madd.php");



            getActivity().setTitle(planet);

            return rootView;
        }
    }
    public static class WebLogoutFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";


        public WebLogoutFragment() {
                // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        {     
            View rootView = inflater.inflate(R.layout.fragment_web, container, false);

            WebView webview;
            webview = (WebView) rootView.findViewById(R.id.webview);

            webview.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    String weburl = view.getUrl();
                    String cookies = CookieManager.getInstance().getCookie(url);
                    getUrl = view.getUrl();
                    isUserLoggedIn=IsLoggedIn();
                    Log.d(TAG, "All the cookies in a string:" + cookies);
                    if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php")) {
                        mDrawerList.setItemChecked(0, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php?log=1")) {
                        mDrawerList.setItemChecked(0, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mtimecounter.php")) {
                        mDrawerList.setItemChecked(1, true);
                        getActivity().getActionBar().setTitle("כניסה/יציאה");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/madd.php")) {
                        mDrawerList.setItemChecked(2, true);
                        getActivity().getActionBar().setTitle("הוספת אירוע");
                    } else if (weburl.equals("http://www.klh-dev.com/lehava/lehava/system/mlogin.php?log=1")) {
                        mDrawerList.setItemChecked(2, true);
                        getActivity().getActionBar().setTitle("התחברות");
                    }
                }
            });
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setUseWideViewPort(true);
            webview.setWebChromeClient(new WebChromeClient());
            webview.loadUrl("http://www.klh-dev.com/lehava/lehava/system/mlogout.php");


            return rootView;
        }
    }

    public static BasicCookieStore getCookieStore(String cookies, String domain) {
        String[] cookieValues = cookies.split(";");
        BasicCookieStore cs = new BasicCookieStore();

        BasicClientCookie cookie;
        for (int i = 0; i < cookieValues.length; i++) {
            String[] split = cookieValues[i].split("=");
            if (split.length == 2)
                cookie = new BasicClientCookie(split[0], split[1]);
            else
                cookie = new BasicClientCookie(split[0], null);

            cookie.setDomain(domain);
            cs.addCookie(cookie);
        }
        return cs;

        }

这是我的错误:

public void UpdateMenu() {

    //mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    //mDrawerList = (ListView) findViewById(R.id.left_drawer);
        if (isUserLoggedIn == null) {
            isUserLoggedIn = IsLoggedIn();
            if (isUserLoggedIn.equals("0")) {
                mPlanetTitles = Arrays.copyOfRange(mPlanetTitles, 1, 2);
            }
        }

        showToast(mPlanetTitles[1]);

}
public void showToast(final String toast)
{
    runOnUiThread(new Runnable() {
        public void run()
        {
            Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
        }
    });
}

只要它尝试显示吐司,应用就会崩溃。 这是错误:

02-01 14:41:50.976: E/AndroidRuntime(25010): FATAL EXCEPTION: main
02-01 14:41:50.976: E/AndroidRuntime(25010): Process: com.klh.lehava, PID: 25010
02-01 14:41:50.976: E/AndroidRuntime(25010): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
02-01 14:41:50.976: E/AndroidRuntime(25010):    at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:105)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at com.klh.lehava.MainActivity$3.run(MainActivity.java:663)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at android.os.Handler.handleCallback(Handler.java:739)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at android.os.Handler.dispatchMessage(Handler.java:95)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at android.os.Looper.loop(Looper.java:135)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at android.app.ActivityThread.main(ActivityThread.java:5221)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at java.lang.reflect.Method.invoke(Native Method)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at java.lang.reflect.Method.invoke(Method.java:372)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
02-01 14:41:50.976: E/AndroidRuntime(25010):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我已经阅读了与我相同的其他5个问题,但没有一个有效。

第662 - 664行:

}
public void showToast(final String toast)
{

编辑(IsLoggedIn):

public static String IsLoggedIn() {
    new Thread(new Runnable() {
        @Override
        public void run() {
                 String cookies = CookieManager.getInstance().getCookie(getUrl);
                 BasicCookieStore lCS = getCookieStore(cookies, "klh-dev.com");

                 HttpContext localContext = new BasicHttpContext();
                 DefaultHttpClient httpclient = new DefaultHttpClient();
                 httpclient.setCookieStore(lCS);
                 localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);

            HttpGet get = new HttpGet("http://klh-dev.com/lehava/lehava/system/isloggedin.php");


            try {
                result=httpclient.execute(get,localContext);
                response_str = EntityUtils.toString(result.getEntity());
                System.out.println(response_str);
                MenuChecker.UpdateMenu();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }).start();
    return response_str;
}

请帮助我,我阅读了大量的教程,尝试了很多不同的方法,没有任何效果。 谢谢。

3 个答案:

答案 0 :(得分:0)

static MainActivity MenuChecker = new MainActivity();

永远不要使用new实例化活动。它们对您使用Activity的任何内容都没有任何好处,例如Context

相反,将Context作为参数传递给那些需要它的方法。

答案 1 :(得分:0)

Execute runOnUiThread method using activity like

this.runOnUiThread(new Runnable() 
{
 public void run()
        {
            Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
        }
    });

OR

Activity activity = // reference to an Activity
activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
         Toast.makeText(activity, toast, Toast.LENGTH_SHORT).show();
    }
});

答案 2 :(得分:0)

使用此方法解决:

 private static MainActivity instance;

    public MainActivity() {
        instance = this;
    }

并将showtoast脚本更改为:

Toast.makeText(instance, toast, Toast.LENGTH_SHORT).show();
相关问题