Украшение реализации (не контракта) метода с OperationBehaviorAttribute.AutoDisposeParameters = false
делает работу.
Здесь был мой контракт
[ServiceContract]
public interface IStorageBackendSvc {
...
[OperationContract]
[FaultContract(typeof(DescriptiveFault))]
Task AcceptWmaMediaType(int stationId, OpaqueMediaType mediaType);
}
Вот реализация:
[OperationBehavior(AutoDisposeParameters = false)]
Task IStorageBackendSvc.AcceptWmaMediaType(int stationId, OpaqueMediaType mediaType) {
try {
WmaWriter wmaWriter = GetWmaWriter(stationId);
wmaWriter.MediaType = mediaType;
return Task.CompletedTask;
} catch( Exception exception ) {
throw _faultFactory.Wrap(exception);
}
}
Теперь параметр mediaType
не , а не , поэтому кэшированная ссылка сохраняется в силе, и я мог обойти выполнение глубокого копирования параметра.
Редактировать: Что касается сомнений в том, как объект кэшируется, вот код:
private Dictionary<int, WmaWriter> _wmaWriters;
private WmaWriter GetWmaWriter(int stationId) {
WmaWriter wmaWriter;
lock( _wmaWriters ) {
if( !_wmaWriters.TryGetValue(stationId, out wmaWriter) ) {
wmaWriter = new WmaWriter(stationId, new DailyFileSplitter(), new WmaFileNameResolver(stationId));
_wmaWriters[stationId] = wmaWriter;
}
}
return wmaWriter;
}
_wmaWriters
является членом службы. Это словарь, в котором хранятся несколько устройств записи WMA, снабженных ключом с помощью идентификатора станции (я записываю несколько теле- и радиостанций). Метод GetWmaWriter()
возвращает существующий модуль записи WMA, связанный с определенной станцией, или создает новый, если его нет. существует. Кэширование эффективно, потому что для нескольких вызовов одного и того же идентификатора станции я получу один и тот же экземпляр WmaWriter.
Это работало со следующим кодом, допустил, что я был маленькими немыми с последним. Я все еще думаю, там получен, чтобы быть лучшим путем так, чтобы исходный образ был все еще сохранен где-нибудь. Это все еще отправляет мне меньшее изображение 25% размером.
public class CameraTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button cameraButton = (Button) findViewById(R.id.cameraButton);
cameraButton.setOnClickListener( new OnClickListener(){
public void onClick(View v ){
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent,0);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode== 0 && resultCode == Activity.RESULT_OK) {
Bitmap x = (Bitmap) data.getExtras().get("data");
((ImageView)findViewById(R.id.pictureView)).setImageBitmap(x);
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, "title");
values.put(Images.Media.BUCKET_ID, "test");
values.put(Images.Media.DESCRIPTION, "test Image taken");
values.put(Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
OutputStream outstream;
try {
outstream = getContentResolver().openOutputStream(uri);
x.compress(Bitmap.CompressFormat.JPEG, 70, outstream);
outstream.close();
} catch (FileNotFoundException e) {
//
} catch (IOException e) {
//
}
}
}
Кроме того, я действительно знаю, что выпуск капкейка Android должен скоро зафиксировать небольшой размер изображения.
При первой попытке приложение "Камера" может вылетать, когда оно читает ваш «вывод» дополнительно, поскольку он ожидает, что это будет Uri, в то время как вы предоставляете String. Кажется, что приложение камеры считывает дополнительный флаг после съемки фотографии. Вы должны просто указать uri, а не uri.getPath (). Затем, поскольку вы уже знаете URI фотографии, он не будет возвращен в вызове onResult. Вам необходимо запомнить URI в переменной-члене.
Во второй попытке вы получите обратно уменьшенное (50%) растровое изображение. Он в первую очередь предназначен для просмотров. Я думаю, что полноразмерное растровое изображение слишком велико для бюджета памяти приложения. Это может быть причиной уменьшения масштаба.
У меня та же проблема с эмулятором, я пробовал это на реальном телефоне, и это сработало, может быть потому что виртуальный телефон действительно не может принимать картинки.
К вашему сведению, нашел это в документах: Вызывающий может передать дополнительный EXTRA_OUTPUT, чтобы контролировать, где будет записано это изображение. Если EXTRA_OUTPUT отсутствует, то изображение небольшого размера возвращается как объект Bitmap в дополнительном поле. Это полезно для приложений, которым требуется только небольшое изображение. Если присутствует EXTRA_OUTPUT, то полноразмерное изображение будет записано в значение Uri EXTRA_OUTPUT.
находится здесь: http://developer.android.com/reference/android/provider/MediaStore.html
, чтобы приложение могло сохранить для вас полноразмерное изображение, если вы укажете его где.
** Edit: Это не относится к устройствам HTC. HTC (не nexus), использующий интерфейс htc sense, отличается от Android 1.5 и содержит ошибку, которая всегда сохраняет изображение в низком разрешении. вы можете пообедать с камерой и использовать функцию обмена с камеры, чтобы использовать полноразмерное изображение.