【问题标题】:App crashes after intent to activity using background thread使用后台线程进行活动后应用程序崩溃
【发布时间】:2015-11-03 17:20:54
【问题描述】:

我已经遇到这个问题一整天了。我制作了一个应用程序,它使用 JSON 从我的服务器获取数据并将其转换并显示在应用程序中。我把它作为一个单独的工作应用程序,只有一个活动。下一步是制作一个使用多个活动的应用程序。我制作了一个带有按钮的主屏幕,该按钮旨在与其他应用程序一样工作的活动。当我打开应用程序时,一切正常,但是当我打算进入另一个(接收)屏幕时,应用程序崩溃了。我想这是因为它没有在 ui 线程上运行,但我无法弄清楚.. 如果有人可以帮助我,那就太好了!提前非常感谢。

错误

11-03 18:03:35.460    6159-6235/me.janvandijk.receptenapp E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: me.janvandijk.receptenapp, PID: 6159
java.lang.RuntimeException: An error occured while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:304)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
        at android.os.Handler.<init>(Handler.java:200)
        at android.os.Handler.<init>(Handler.java:114)
        at android.app.Activity.<init>(Activity.java:794)
        at me.janvandijk.receptenapp.Recepten.<init>(Recepten.java:24)
        at me.janvandijk.receptenapp.ReceptenDefine.<init>(ReceptenDefine.java:12)
        at me.janvandijk.receptenapp.Recepten$ReceptenAsynTask.doInBackground(Recepten.java:60)
        at me.janvandijk.receptenapp.Recepten$ReceptenAsynTask.doInBackground(Recepten.java:42)
        at android.os.AsyncTask$2.call(AsyncTask.java:292)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:818)

JSON:

[{"id":"1",
    "naam":"Bastogneparfait a la Kim",
    "beschrijving":"Gemaakt van Bastogne, het lekkerste gerecht ooit!",
    "ingredienten":"Bastogne parfait ingredi\u00ebnten\r\n40 gram eierdooiers (gepasteuriseerd)\r\n45 gram hele eieren (gepasteuriseerd)\r\n100 gram suiker \r\n2,5 dl slagroom ongezoet\r\n4  bastognekoeken \r\nKaralmelsaus ingredi\u00ebnten\r\n100 gram suiker \r\n2 dl koksroom ",
    "bereiding":"Slagroom opkloppen tot yoghurt dikte. De eidooiers, hele eieren en suiker in een bekken doen en au bain-marie verwarmen tot 37 graden Celsius. Koud kloppen in de keukenmachine tot een luchtige massa. Spatel de massa door de slagroom. Kruimel de bastognekoeken en spatel ze voorzichtig door de massa. Vul de vormpjes en zet in diepvries.\nBereidingswijze karamelsaus\nDoe de suiker in een pan en verwarm de suiker tot deze is gekaramelliseerd. Haal de pan van het vuur en voeg de koksroom toe. Laat de karamel goed oplossen in de koksroom regelmatig roeren. Als de massa glad is af laten koelen.\nOpdienen\nHaal de parfait uit de vorm en leg in een tapasschaaltje. Doe er karamelsaus bij en een toefje slagroom op de parfait. Eventueel af garneren met een takje mint.",
    "auteur":"3",
    "timestamp":"2015-10-22 14:42:14"},
{"id":"2",
    "naam":"Vlindertjes met kip, spekjes en roomsaus",
    "beschrijving":"Lekker lekker!",
    "ingredienten":"Een beetje liefde\r\nEen beetje kip\r\nEen beetje spekjes\r\nEen beetje kruidenshit\r\nEen beetje creeemeee freeescheee\r\nEn vlindertjes",
    "bereiding":"In pan hop klaar!",
    "auteur":"1",
    "timestamp":"2015-11-02 09:50:54"}]

公共类 Home 扩展了 Activity

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

public void showReceptenScherm(View view){
    Intent intent = new Intent(Home.this, Recepten.class);
    startActivity(intent);
}

@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_home, menu);
    return true;
}

public void onRadioButtonClicked(View view) {
    Toast.makeText(getApplicationContext(), "Sending your vote..", Toast.LENGTH_LONG).show();


}

Recepten 活动

    ListView list;
ReceptenAdapter adapter;
ArrayList<ReceptenDefine> receptenList;

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

    list = (ListView)findViewById(R.id.receptenList);
    receptenList = new ArrayList<>();

    new ReceptenAsynTask().execute("http://janvandijk.me/zooi/receptenapp/getrecipes.php?type=request&datatype=recepten");
}


public class ReceptenAsynTask extends AsyncTask<String, Void, Boolean> {

    @Override
    protected Boolean doInBackground(String... params) {
        try {
            HttpClient client = new SystemDefaultHttpClient();
            HttpPost post = new HttpPost(params[0]);
            HttpResponse response = client.execute(post);

            int status = response.getStatusLine().getStatusCode();

            if (status == 200){
                HttpEntity entity = response.getEntity();
                String data = EntityUtils.toString(entity);

                JSONArray jArray = new JSONArray(data); //jArray.length()
                for (int i=0; i<jArray.length(); i++){
                    ReceptenDefine recept;
                    recept = new ReceptenDefine();

                    JSONObject jRealObject = jArray.getJSONObject(i);

                    recept.setReceptnaam(jRealObject.getString("naam"));
                    recept.setReceptauthor(jRealObject.getString("id"));
                    recept.setReceptimageurl("http://www.crossfitswarm.com/wp-content/uploads/2013/03/food-photo-200x200.png");
                    recept.setReceptrating(jRealObject.getString("ingredienten"));

                    receptenList.add(recept);

                }
                return true;


            }

        } catch (JSONException | IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean result){
        super.onPostExecute(result);

        if(!result){
            //Show message that data wasn't parsed
        } else {
            ReceptenAdapter adapter = new ReceptenAdapter(getApplicationContext(), R.layout.row, receptenList);
            list.setAdapter(adapter);
        }



    }
}

@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_recepten, 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);
}

接受定义

public class ReceptenDefine extends Recepten {
private String receptnaam;
private String receptauthor;
private String receptimageurl;
private String receptrating;

public ReceptenDefine(){

}

public String getReceptnaam() {
    return receptnaam;
}

public void setReceptnaam(String receptnaam) {
    this.receptnaam = receptnaam;
}

public String getReceptauthor() {
    return receptauthor;
}

public void setReceptauthor(String receptauthor) {
    this.receptauthor = receptauthor;
}

public String getReceptimageurl() {
    return receptimageurl;
}

public void setReceptimageurl(String receptimageurl) {
    this.receptimageurl = receptimageurl;
}

public String getReceptrating() {
    return receptrating;
}

public void setReceptrating(String receptrating) {
    this.receptrating = receptrating;
}

接收适配器

public class ReceptenAdapter extends ArrayAdapter<ReceptenDefine>{

ArrayList<ReceptenDefine> ArrayListRecepten;
int Resource;
Context context;
LayoutInflater vi;


public ReceptenAdapter(Context context, int resource, ArrayList<ReceptenDefine> objects) {
    super(context, resource, objects);

    ArrayListRecepten = objects;
    Resource = resource;
    this.context = context;

    vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //Verschillende items laten zien

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    if(convertView == null){
        //Eerste listview item wordt gemaakt
        convertView = vi.inflate(Resource, null);
        holder = new ViewHolder();

        //Set all textview and imageview dingen



        holder.listImage = (ImageView)convertView.findViewById(R.id.listImage);
        holder.listAuthor = (TextView)convertView.findViewById(R.id.listAuthor);
        holder.listName = (TextView)convertView.findViewById(R.id.listName);
        holder.listRating = (TextView)convertView.findViewById(R.id.listRating);

        //Zet het neer
        convertView.setTag(holder);
    } else {
        //volgende list items, doe alles opnieuw zetten
        holder = (ViewHolder)convertView.getTag();
    }

    new DownloadImageTask(holder.listImage).execute(ArrayListRecepten.get(position).getReceptimageurl());
    holder.listName.setText(ArrayListRecepten.get(position).getReceptnaam());
    holder.listAuthor.setText(ArrayListRecepten.get(position).getReceptauthor());
    holder.listRating.setText(ArrayListRecepten.get(position).getReceptrating());
    return convertView;
}

static class ViewHolder {
    public ImageView listImage;
    public TextView listName;
    public TextView listAuthor;
    public TextView listRating;
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }
    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

}

【问题讨论】:

标签: java android json android-intent


【解决方案1】:

这里:

public class ReceptenDefine extends Recepten {
 ...                                 ^^^^^^
}

ReceptenDefine 类中扩展 Recepten 的子类 Activity 会导致问题。

因为ReceptenDefine 类只包含getter-setter 方法,所以不需要为这个类扩展ActivityRecepten 类。把它当作普通类使用。

要解决问题,请从 ReceptenDefine 类中删除扩展:

public class ReceptenDefine {
 ...                                
}

【讨论】:

  • 非常感谢!如此愚蠢的错误..我整天都在看。再次感谢!
猜你喜欢
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2018-07-09
  • 2019-06-02
  • 1970-01-01
  • 2017-02-13
  • 2019-03-29
相关资源
最近更新 更多