Не удается запустить службу во внутреннем классе - это мой манифест Android?

1

Пожалуйста помоги! Я в отчаянии здесь !!!!

У меня возникли проблемы с началом службы. Я переместил его во внутренний класс внутри своей деятельности, и я не могу заставить его начать!

Я не знаю, должен ли я что-то изменить в своем манифесте или назвать его по-другому.

Я пробовал называть его с помощью "Intent intent = new Intent (HW07.this, PrimeService.class)"; и я получил следующую ошибку:

05-24 13: 15: 22.662: W/ActivityManager (80): Не удалось запустить сервис Intent {cmp = jschuler.cs211d.hw07/.HW07 $ PrimeService (имеет дополнительные функции)}: не найден

Когда я называю это без HW07, я получаю ту же ошибку.

Есть идеи? Вот мой код:

package jschuler.cs211d.hw07;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import android.os.Handler;
import android.content.Intent;
import android.os.Message;
import android.util.Log;
import android.app.Service;
import android.os.IBinder;

public class HW07 extends Activity implements View.OnKeyListener
{
    String howMany, upper, lower, values;
    TextView tv_howMany, tvUpper, tvLower, test;
    EditText howManyInput, upperInput, lowerInput;
    //Handler h = new Handler();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv_howMany = (TextView) findViewById(R.id.how_many);
        tv_howMany.setText("How many primes would you like to generate?");

        howManyInput = (EditText) findViewById(R.id.input1);
        howManyInput.setOnKeyListener(this);        

        tvUpper = (TextView) findViewById(R.id.upper);
        tvUpper.setText("Upper limit:");

        upperInput = (EditText) findViewById(R.id.input2);
        upperInput.setOnKeyListener(this);        

        tvLower = (TextView) findViewById(R.id.lower);
        tvLower.setText("Lower limit:");

        lowerInput = (EditText) findViewById(R.id.input3);
        lowerInput.setOnKeyListener(this);        

        test = (TextView) findViewById(R.id.test);
    }

    Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            Log.d("handleMessage","message handled!");
            Toast.makeText(getApplicationContext(), "in handleMessage", Toast.LENGTH_LONG).show();
            String primes = msg.obj.toString();
            Log.d("handleMessage!","Here are the primes: " + primes);
            super.handleMessage(msg);

        }
    };

    public boolean onKey(View v, int keyCode, KeyEvent ke)
    {
        if( (ke.getAction() == KeyEvent.ACTION_DOWN) &&
            (keyCode == KeyEvent.KEYCODE_ENTER) )
        {
            values = howManyInput.getText().toString() + "," +
                upperInput.getText().toString() + "," +
                lowerInput.getText().toString();
            test.setText(values);

            //handler.sendMessage(handler.obtainMessage(null, values));

            Intent intent = new Intent(this, PrimeService.class);
            intent.putExtra("parameters",values);
            startService(intent);

            return true;
        }
        return false;
    }

    public class PrimeService extends Service
    {
        @Override
        public IBinder onBind(Intent args)
        {
            return null;
        }

        @Override
        public int onStartCommand(Intent i, int flags, int startId)
        {
            Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();

            String parameters = i.getExtras().getString("parameters");
            Log.d("onStartCommand","parameters: " + parameters);
            //Handler serviceHandler = new Handler();

            String result = generatePrimes("Primes");
            //serviceHandler.sendMessage(serviceHandler.obtainMessage(0, result));    

            handler.sendMessage(handler.obtainMessage(0, result));  

            /* Thread t = new Thread( new Runnable() 
            {
                public void run() 
                {
                    String result = generatePrimes("Primes");

                    handler.sendMessage(handler.obtainMessage(0, result));  
                }

            });
            t.start();
     */
            return START_STICKY;
        }    

    /*     Handler serviceHandler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
                Message primeMsg = serviceHandler.obtainMessage();
                String primes = primeMsg.obj.toString();

                //serviceHandler.sendMessage(serviceHandler.obtainMessage(0, result));    

                Log.d("handleMessage","primes: "+primes);

                super.handleMessage(msg);
            }
        }; */

        public String generatePrimes(String p)
        {
            return p;    
        }

        @Override
        public void onDestroy()
        {
            super.onDestroy();
            Toast.makeText(this,"Service Destroyed",Toast.LENGTH_LONG).show();
        }
    }
}

Вот мой манифест Android:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jschuler.cs211d.hw07"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
        <activity android:name="HW07"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".PrimeService">
            <intent-filter>
                <action android:name="jschuler.cs211d.hw07"/>
            </intent-filter>
        </service>
    </application>
</manifest>

Я изменил код в PrimeService... теперь я просто пытаюсь получить свою строку из потока (в том же классе). Я получил его, чтобы работать до этого, но он не работает на этот раз.

Вот мой новый код:

package jschuler.cs211d.hw07;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import java.net.*;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class PrimeService extends Service
{
    String str;

    @Override
    public IBinder onBind(Intent args)
    {
        return null;
    }

    @Override
    public int onStartCommand(Intent i, int flags, int startId)
    {
        Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();

        String parameters = i.getExtras().getString("parameters");
        Log.d("onStartCommand","parameters: " + parameters);
        //Handler serviceHandler = new Handler();

        String result = generatePrimes("Primes");
        Log.d("result","result: "+result);
        Message primeMessage = receiveHandler.obtainMessage(0, result);
        receiveHandler.sendMessage(primeMessage);

        /* Handler sendHandler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
                Log.d("sendHandler","handleMessage called");
                String result = generatePrimes("Primes");
                Message primeMessage = receiveHandler.obtainMessage();
                primeMessage.obj = result;
                receiveHandler.sendMessage(primeMessage);
                super.handleMessage(msg);
            }
        }; */

        // IF I GET THE ABOVE CODE TO WORK, I WILL PUT IT IN THIS THREAD!!!

        /* Thread t = new Thread( new Runnable() 
        {
            public void run() 
            {
                receiveHandler.sendMessage(receiveHandler.obtainMessage(0, generatePrimes("prime numbers")));    

                //String result = generatePrimes("Primes");
                //serviceHandler.sendMessage(serviceHandler.obtainMessage(0, result));  
            }

        });
        t.start(); */

        return START_STICKY;
    }        

    Handler receiveHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            //serviceHandler.sendMessage(serviceHandler.obtainMessage(0, generatePrimes("prime numbers")));    

            Message primeMsg = Message.obtain();
            //Message primeMsg = receiveHandler.obtainMessage();
            String primes = (String)primeMsg.obj;

            Log.d("handleMessage","here are the primes: "+primes);

            super.handleMessage(msg);
        }
    };

    public String generatePrimes(String p)
    {
        return p;    
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        Toast.makeText(this,"Service Destroyed",Toast.LENGTH_LONG).show();
    }
}
Теги:
service

2 ответа

3

Ваша Service должна быть статическим классом. Затем один раз в вашем манифесте вам нужно будет показать это так

<service android:name="HW07$PrimeService"/>

Вы могли бы сделать что-то вроде этого (псевдо)

class HM07 extends Activity {

    public static Handler mHandler;
    // ...

    @Override public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        // ...

        mHandler = new Handler();
    }
}

class PrimeService extends Service {
    @Override public void onStartCommand() {
        Handler handler = HM07.mHandler;
        handler.sendMessage(/* Message */);
    }
}
  • 0
    Ааа, статический класс! Это имеет смысл, но ... Когда я объявляю его как статический класс, я получаю ошибку: на обработчик нестатической переменной нельзя ссылаться из статического контекста [javac] handler.sendMessage (handler.obtainMessage (0, result)) ; [javac] ^ Возможно, внутренний класс - это не тот путь. Я не мог заставить Activity и Service взаимодействовать иначе, потому что Обработчики были связаны с разными потоками (и, следовательно, с разными messageQueues), и я не мог заставить их общаться. Есть идеи, что я могу сделать здесь?
  • 0
    Верный. Как правило, не очень хорошая идея иметь статическое внутреннее обслуживание, потому что, чаще всего, это не имеет никакого смысла. Сервис должен быть самодостаточным объектом, который сообщается через ServiceConnection. Используя сервисное соединение, вы получите экземпляр вашего сервиса. Используя этот экземпляр, вы можете «разговаривать» взад и вперед.
Показать ещё 5 комментариев
1
class outclass extends Activity {
   // ...
   @Override
   public void onCreate(Bundle icicle) {
       super.onCreate(icicle);
       // ...
   }

   public static class innerService extends Service {
       @Override
       public void onStartCommand() {
           //....
       }
   }
}

и вам нужно объявить ниже свой Androidmanifest.xml

<service android:name=".outclass$innerService"/>

обратите внимание на знак доллара!

  • 0
    как остановить службу во внутреннем классе от активности

Ещё вопросы

Сообщество Overcoder
Наверх
Меню