在没有来自webservice的数据的情况下显示toast会导致android应用程序崩溃

在没有来自webservice的数据的情况下显示toast会导致android应用程序崩溃,android,web-services,toast,Android,Web Services,Toast,全部。我正在使用一个虚拟应用程序,其中显示来自wheather Web服务的数据。一切正常,但我面临的问题是,当我在没有来自服务器的数据的情况下显示Toast,或者当设备上可能无法使用internet时,我的应用程序在播放时崩溃 "Unfortunately wheather app stopped working " 只有当设备上没有internet时,才会出现此问题。当我断开互联网时,给我造成问题的线路如下: Toast.makeText(getApplicationContext(),

全部。我正在使用一个虚拟应用程序,其中显示来自wheather Web服务的数据。一切正常,但我面临的问题是,当我在没有来自服务器的数据的情况下显示Toast,或者当设备上可能无法使用internet时,我的应用程序在播放时崩溃

"Unfortunately wheather app stopped working "
只有当设备上没有internet时,才会出现此问题。当我断开互联网时,给我造成问题的线路如下:

Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();
package com.mubu.wheathertoday.wheathertoday;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONObject;
import org.w3c.dom.Text;


public class MainActivity extends ActionBarActivity {
    EditText etCity;
    Button btnShow;
    ProgressDialog pbar;
    String JsonString;
    TextView tvr;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         etCity=(EditText)findViewById(R.id.etCity);
        btnShow=(Button)findViewById(R.id.btnShow);


        btnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                AsyncGetData gd=new AsyncGetData();
                gd.execute();
            }

        });

    }


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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    private  class AsyncGetData extends AsyncTask<Void,Void,Void>{


        @Override
        protected Void doInBackground(Void... params) {
  try {
      ServiceHandler sh = new ServiceHandler();
      String url="http://api.openweathermap.org/data/2.5/weather?q="+etCity.getText().toString().trim();
    JsonString = sh.makeServiceCall(url, ServiceHandler.POST);
      if (JsonString != null) {
         Intent i=new Intent(getApplicationContext(),WheatherActivity.class);
          try{
          i.putExtra("jsn",JsonString);
         i.putExtra("city",etCity.getText().toString());
           startActivity(i);
          }catch (Exception e){


      }
      }
      else
      {
    try{

       Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();


 // if I disconnect Internet this line gets executed and my app crashes
            }catch (Exception e){


}
      }

      }
  catch (Exception e){etCity.setText(e.getMessage());}
            return null;

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

              pbar=new ProgressDialog(MainActivity.this);
            pbar.setMessage("Please wait...");
            pbar.setCancelable(false);
            pbar.show();
        }

        @Override
        protected void onPostExecute(Void s) {
            super.onPostExecute(s);
           if(pbar.isShowing() )
                pbar.dismiss();


        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }

}
如果我评论这句话,我的应用程序运行良好。我在此文件中的所有代码如下所示:

Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();
package com.mubu.wheathertoday.wheathertoday;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONObject;
import org.w3c.dom.Text;


public class MainActivity extends ActionBarActivity {
    EditText etCity;
    Button btnShow;
    ProgressDialog pbar;
    String JsonString;
    TextView tvr;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         etCity=(EditText)findViewById(R.id.etCity);
        btnShow=(Button)findViewById(R.id.btnShow);


        btnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                AsyncGetData gd=new AsyncGetData();
                gd.execute();
            }

        });

    }


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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    private  class AsyncGetData extends AsyncTask<Void,Void,Void>{


        @Override
        protected Void doInBackground(Void... params) {
  try {
      ServiceHandler sh = new ServiceHandler();
      String url="http://api.openweathermap.org/data/2.5/weather?q="+etCity.getText().toString().trim();
    JsonString = sh.makeServiceCall(url, ServiceHandler.POST);
      if (JsonString != null) {
         Intent i=new Intent(getApplicationContext(),WheatherActivity.class);
          try{
          i.putExtra("jsn",JsonString);
         i.putExtra("city",etCity.getText().toString());
           startActivity(i);
          }catch (Exception e){


      }
      }
      else
      {
    try{

       Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();


 // if I disconnect Internet this line gets executed and my app crashes
            }catch (Exception e){


}
      }

      }
  catch (Exception e){etCity.setText(e.getMessage());}
            return null;

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

              pbar=new ProgressDialog(MainActivity.this);
            pbar.setMessage("Please wait...");
            pbar.setCancelable(false);
            pbar.show();
        }

        @Override
        protected void onPostExecute(Void s) {
            super.onPostExecute(s);
           if(pbar.isShowing() )
                pbar.dismiss();


        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }

}
package com.mubu.wheathertoday.wheathertoday;
导入android.app.ProgressDialog;
导入android.content.Intent;
导入android.os.AsyncTask;
导入android.support.v7.app.ActionBarActivity;
导入android.os.Bundle;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.view.view;
导入android.widget.Button;
导入android.widget.EditText;
导入android.widget.TextView;
导入android.widget.Toast;
导入org.json.JSONObject;
导入org.w3c.dom.Text;
公共类MainActivity扩展了ActionBarActivity{
编辑城市;
按钮显示;
pbar;
字符串JsonString;
文本视图tvr;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etCity=(EditText)findViewById(R.id.etCity);
btnShow=(按钮)findViewById(R.id.btnShow);
btnShow.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
AsyncGetData gd=新建AsyncGetData();
gd.execute();
}
});
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(右菜单菜单菜单主菜单);
返回true;
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
//处理操作栏项目单击此处。操作栏将
//自动处理Home/Up按钮上的点击,只要
//在AndroidManifest.xml中指定父活动时。
int id=item.getItemId();
//noinspection SimplifiableIf语句
if(id==R.id.action\u设置){
返回true;
}
返回super.onOptionsItemSelected(项目);
}
私有类AsyncGetData扩展AsyncTask{
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
ServiceHandler sh=新的ServiceHandler();
字符串url=”http://api.openweathermap.org/data/2.5/weather?q=“+etCity.getText().toString().trim();
JsonString=sh.makeServiceCall(url,ServiceHandler.POST);
if(JsonString!=null){
Intent i=新的Intent(getApplicationContext(),wheatheActivity.class);
试一试{
i、 putExtra(“jsn”,JsonString);
i、 putExtra(“city”,etCity.getText().toString());
星触觉(i);
}捕获(例外e){
}
}
其他的
{
试一试{
Toast.makeText(getApplicationContext(),“无法连接”,Toast.LENGTH_LONG.show();
//如果我断开互联网连接,这条线路将被执行,我的应用程序将崩溃
}捕获(例外e){
}
}
}
catch(异常e){etCity.setText(e.getMessage());}
返回null;
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
pbar=新建进度对话框(MainActivity.this);
设置消息(“请稍候…”);
pbar.setCancelable(假);
pbar.show();
}
@凌驾
受保护的void onPostExecute(void s){
super.onPostExecute(s);
if(pbar.isShowing())
pbar.discouse();
}
@凌驾
受保护的void onProgressUpdate(void…值){
super.onProgressUpdate(值);
}
}
}

也许你不应该在“doInbackground”里烤面包。因为它不是UI线程


试着在“onPostExecute”中做这件事。

也许你不应该在“doInbackground”中做吐司。因为它不是UI线程


尝试在“onPostExecute”中执行此操作。

您正在尝试在
doInBackground
中显示Toast。不应从该方法调用任何与UI相关的功能,因为这是后台线程。您必须从
onPostExecute

显示toast,您正试图在
doInBackground
中显示toast。不应从该方法调用任何与UI相关的功能,因为这是后台线程。您必须在onPostExecute中显示toast

您要做的是在后台显示toast,但您不能这样做如果您要显示toast,则必须在onPostExecute中编写该段代码

您可以做的是,您必须在asyntask Cals中创建一个布尔变量,假设名为_is_response_Received=false

而且

if (JsonString != null) {
 _Is_Responce_Received=true;
  // rest of your code

 }
在你的岗位上执行

  @Override
    protected void onPostExecute(Void s) {
        super.onPostExecute(s);

 if(!_Is_Responce_Received){
    Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();
  }
       if(pbar.isShowing() )
            pbar.dismiss();


    }

您要做的是在后台显示toast,但您不能这样做,如果您想显示toast,您必须在onPostExecute中编写这段代码

您可以做的是,您必须在asyntask Cals中创建一个布尔变量,假设名为_is_response_Received=false

而且

if (JsonString != null) {
 _Is_Responce_Received=true;
  // rest of your code

 }
在你的岗位上执行

  @Override
    protected void onPostExecute(Void s) {
        super.onPostExecute(s);

 if(!_Is_Responce_Received){
    Toast.makeText(getApplicationContext(),  "Not able to connect", Toast.LENGTH_LONG).show();
  }
       if(pbar.isShowing() )
            pbar.dismiss();


    }

问题是您试图从
doInBackground
更新用户界面
doInBackground
在后台线程中运行,而不是在主线程(也称为UI线程)中运行

正如您在文档中看到的(我的重点):

onPreExecute(),在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如在用户界面中显示进度条

doInBackground(Params…,在后台线程上调用